Подтвердить что ты не робот

Экран заставки до тех пор, пока нить не закончится

У меня все еще проблема с заставкой. Я не хочу использовать свойство SC.TopMost=true.

Теперь мой сценарий приложения выглядит следующим образом:

в progeram.cs:

[STAThread]
static void Main()
{
    new SplashScreen(_tempAL);// where _tempAL is an arrayList
    Application.Run(new Form1(_tempAL));
}

в классе SplashScreen:

public SplashScreen(ArrayList _Data)
{
    DisplaySplash()
} 
private void DisplaySplash()
{
    this.Show();
    this.TopMost = true;
    this.CenterToScreen();
    this.SetTopLevel(true);

    _allServerNarrators = new string[10];
    for (int i = 0; i < _allServerNarrators.Length; i++)
        _allServerNarrators[i] = null;

    GetFromServer();

    this.Hide();
    _serverData = new ArrayList();
    _thisData.Add(_allServerNarrators);
    _thisData.Add(_serverNarrators);

}
private void GetFromServer()
{
    _serverNarrators = new ArrayList();
    string _file = "Suras.serverNar";

    if (!Directory.Exists("c:\\ASGAQuraan"))
        Directory.CreateDirectory("c:\\ASGAQuraan");

    while (counter < 4 && _serverFiles == null)
    {
        if (Download("c:\\ASGAQuraan", _ftpServerIP, _file))
        {
            StreamReader _strReader = new StreamReader
                         ("c:\\ASGAQuraan\\"+_file,System.Text.Encoding.Default);
            string _line = _strReader.ReadLine();
            string _word;

            while (true)
            {
                while (_line != null)
                {
                    _word = _line.Substring(0, _line.IndexOf("*"));
                    int _narId = Convert.ToInt32(_word);
                    _line = _line.Substring(2);
                    int k = 0;
                    _serverNarratorNode = new ArrayList();
                    while (true)
                    {
                        int ind = _line.IndexOf("*");
                        if (ind > 0 && ind < _line.Length)
                        {
                            string str = _line.Substring(0, (ind));
                            if (k == 0)
                            {
                                _allServerNarrators[_narId] = str;
                                _serverNarratorNode.Add(str);
                            }
                            else
                            {
                                _serverNarratorNode.Add(str);
                            }
                            _line = _line.Substring(ind + 1);
                            k++;
                        }
                        else
                        {
                            _line = null;
                            break;
                        }
                    }
                    _serverNarrators.Add(_serverNarratorNode);
                    _serverFiles = "added";
                }
                _line = _strReader.ReadLine();
                if (_line == null)
                {
                    break;
                }
            }
        }
        else
            counter++;
    }
}

То, что я хочу, это что-то в классе заставки, который ждет, пока поток не закончится.

За более подробной информацией, пожалуйста, скажите мне, что мне нужно вам сказать.

4b9b3361

Ответ 1

После двух потоков немного запутывает, но я собираюсь взять удар и сказать это...

Я не совсем понимаю ваш дизайн здесь, но если проблема в том, что при запуске второго приложения форма экрана заставки становится белой... Скорее всего, это связано с тем, что заставка заполнена, выполняя все это код в GetFromServer(). Так занят, что у него нет времени, чтобы перекрасить себя.

Чтобы исправить эту проблему, я предлагаю вам использовать компонент BackGroundWorker для выполнения метода GetFromServer. Это запустит этот метод в отдельном потоке и оставьте поток в форме без повторного рисования.

Ответ 2

Тот же вопрос, тот же ответ:

.NET framework имеет отличную встроенную поддержку заставки. Запустите новый проект WF, Project + Add Reference, выберите Microsoft.VisualBasic. Добавьте новую форму, назовите ее frmSplash. Откройте Project.cs и сделайте так:

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;

namespace WindowsFormsApplication1 {
  static class Program {
    [STAThread]
    static void Main(string[] args) {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      new MyApp().Run(args);
    }
  }
  class MyApp : WindowsFormsApplicationBase {
    protected override void OnCreateSplashScreen() {
      this.SplashScreen = new frmSplash();
    }
    protected override void OnCreateMainForm() {
      // Do your time consuming stuff here...
      //...
      System.Threading.Thread.Sleep(3000);
      // Then create the main form, the splash screen will close automatically
      this.MainForm = new Form1();
    }
  }
}

Ответ 3

Вы вошли в опасную территорию, создав пользовательский интерфейс перед вызовом Application.Run(). Application.Run - это, по сути, ваш программный насос сообщений. Отображая пользовательский интерфейс перед запуском насоса сообщений приложения, вы делаете типичное взаимодействие с пользовательским интерфейсом практически невозможным при преждевременном пользовательском интерфейсе. Для экрана заставки это может показаться нецелесообразным, но имеет значение, если (например, есть запрос на удаление экрана всплеска, если он щелкнул, или вы хотите использовать BackgroundWorker.

Это можно обойти, создав насос сообщений в вашем заставке (сделав его модальным с помощью вызова ShowDialog() вместо Show()), но что обращение с симптомом при рассмотрении проблемы действительно не так трудно.

Я бы настоятельно рекомендовал nobugz answer в этом случае. Структура обеспечивает необходимую поддержку. Хотя функции в пространстве имен Microsoft.VisualBasic не всегда доступны для программистов на С#, они могут быть реальным временным ресурсом и спасателем для таких случаев.

Удачи!

Ответ 4

Вы действительно должны дать более подробную информацию о своей проблеме. Я мог быть совершенно неправ, но я сделаю снимок в темноте. Из того, что я представляю, происходит, и вы хотите, вы хотите, чтобы экран заставки отображался, выполнял некоторую обработку в другом потоке, затем экран заставки уходил, когда закончил.

Для этого вам нужно будет переместить вызов GetFromServer() на BackgroundWorker. Затем переместите

    this.Hide();
    _serverData = new ArrayList();
    _thisData.Add(_allServerNarrators);
    _thisData.Add(_serverNarrators);

для обработчика события BackgroundWorker_RunWorkerCompleted.

Чтобы использовать BackgroundWorker:

1) Инициализируйте BackgroundWorker

  BackgroundWorker myWorker = new BackgroundWorker();

2) Добавить обработчики событий

  myWorker.DoWork += new DoWorkEventHandler(myWorker_DoWork);
  //put the work you want done in this one

  myWorker.RunWorkerCompleted += 
      new RunWorkerCompletedEventHandler(myWorker_RunWorkerCompleted);
  //this gets fired when the work is finished

3) Добавить код в обработчики событий.

4) Начните myWorker.RunWorkerAsync(), чтобы начать работать.

Как отдельная заметка, вы, кажется, ничего не делаете с ArrayList, который вы передаете конструктору заставки. Это предназначено?

Ответ 5

К сожалению, у меня недостаточно репутации, чтобы прокомментировать какой-то ответ.:( Это должно быть ответом на комментарий полковника Паники к ответу Ханса.

Его проблема заключалась в том, что за заставкой будет показан MessageBox, показанный с new FormMain(args). Ключ состоит в том, чтобы вызвать MessageBox из потока, за которым запускается заставка:

splashScreen.Invoke(new Action(() => {
    MessageBox.Show(splashScreen, "the message");
}));

Где splashScreen - ссылка на объект заставки, который был создан в OnCreateSplashScreen и, очевидно, должен быть присвоен новому объекту Form1.