Заставка дождавшись, пока поток не завершит
У меня все еще есть проблема с заставкой. Я не хочу использовать это свойство SC.TopMost=true
.
Теперь мой сценарий приложения выглядит следующим образом:
В прогерах.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++;
}
}
То, что мне нужно, - это что-то в классе заставки, которое ждет завершения потока.
Для получения более подробной информации, пожалуйста, скажите мне, что я должен вам сказать.5 ответов:
Следовать через 2 потока немного запутанно, но я собираюсь сделать удар и сказать это...
Я не совсем понимаю ваш дизайн здесь, но если проблема в том, что при запуске второго приложения форма заставки становится белой... Скорее всего, это связано с тем, что splash screen занят выполнением всего этого кода в GetFromServer(). Настолько занят, что у него нет времени перекрашивать себя.
Чтобы исправить эту проблему, я бы предложил вам использовать BackGroundWorker компонент для выполнения метода GetFromServer. Это позволит запустить этот метод в отдельном потоке и оставить поток формы свободным для перерисовки себя.
Тот же вопрос, тот же ответ:
Платформа .NET framework имеет отличную встроенную поддержку заставок. Запустите новый проект WF, Project + Add Reference, выберите Microsoft.Визуальная основа. Добавьте новую форму, назовите ее frmSplash. открыть проект.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(); } } }
Вы вступили на опасную территорию, создав пользовательский интерфейс до вызова приложения.Бежать(). Приложение.Run-это, по сути, насос сообщений вашей программы. Отображая пользовательский интерфейс перед запуском насоса сообщений приложения, вы делаете типичное взаимодействие пользовательского интерфейса практически невозможным на преждевременном пользовательском интерфейсе. Для экрана-заставки это может показаться неуместным, но это будет иметь значение, если (например) есть запрос, чтобы заставить экран-заставку исчезнуть, если он нажат, или вы хотите использовать Фоновый рабочий.
Их можно обойти, создав сообщение pump на экране заставки (сделав его модальным с помощью вызова ShowDialog () вместо Show ()), но это лечение симптома, когда лечение проблемы действительно не так сложно.
Я бы настоятельно рекомендовал ответ нобугза в этом случае. Фреймворк обеспечивает необходимую поддержку. В то время как функции в Microsoft.Пространство имен VisualBasic не всегда доступно для программистов C#, они могут быть настоящий спаситель времени и жизни для таких случаев, как этот.
Удачи!
Вы действительно должны дать более подробную информацию о вашей проблеме. Я могу быть совершенно неправ, но я собираюсь сделать выстрел в темноте. Из того, что я представляю, происходит, и вы хотите, вы хотите, чтобы экран-заставка показывал, выполнял некоторую обработку в другом потоке, а затем экран-заставка исчезал, когда заканчивал.
Чтобы сделать это, вы собираетесь хотите, чтобы переместить
GetFromServer()
вызовBackgroundWorker
. Затем переместитеthis.Hide(); _serverData = new ArrayList(); _thisData.Add(_allServerNarrators); _thisData.Add(_serverNarrators);
Код для обработчика событий
BackgroundWorker_RunWorkerCompleted
.чтобы использовать
BackgroundWorker
:1) инициализировать
BackGroundWorker
BackgroundWorker myWorker = new BackgroundWorker();
2) добавить обработчики событий
3) Добавьте код в обработчики событий. 4) вызовите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
myWorker.RunWorkerAsync()
, чтобы начать работу.В качестве отдельного замечания, вы, кажется, ничего не делаете с
ArrayList
, который вы передаете конструктору заставки. Это специально?
К сожалению, у меня пока недостаточно репутации, чтобы комментировать чей-то ответ. : (Это должно быть ответом на комментарий полковника Паникса на ответ Ганса Пассанта .
Его проблема заключалась в том, чтоMessageBox
, показанный изnew FormMain(args)
, будет показан за заставкой. Ключ состоит в том, чтобы вызвать MessageBox из потока, в котором работает заставка:splashScreen.Invoke(new Action(() => { MessageBox.Show(splashScreen, "the message"); }));
Где
splashScreen
- ссылка на объект заставки, который был создан вOnCreateSplashScreen
и, очевидно, должен быть передан в новый объектForm1
.