启animation面等待,直到线程完成

我仍然有一个启animation面的问题。 我不想使用属性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++; } } 

我想要的是在等待线程结束的初始屏幕类中的东西。

有关更多详情,请告诉我我需要告诉你什么。

以下两个线程有​​点混乱,但我会采取一个刺,并说这个…

我不完全理解你的devise,但是如果问题是当你启动第二个应用程序时,启animation面变成白色……这很可能是由于启animation面忙于执行GetFromServer中的所有代码()。 如此繁忙以至于没有时间重绘自己。

为了解决这个问题,我build议你使用BackGroundWorker组件来执行GetFromServer方法。 这将在单独的线程中运行该方法,并将表单的线程自由地重新绘制。

同样的问题,同样的答案:

.NET框架具有出色的内置支持闪屏。 启动一个新的WF项目,Project +添加引用,selectMicrosoft.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(); } } } 

在调用Application.Run()之前,您已经通过创buildUI来进入危险区域。 Application.Run本质上是你程序的消息泵。 通过在启动应用程序的消息泵之前显示UI,您在过早的用户界面上使典型的UI交互变得不可能。 对于启animation面来说,这可能看起来并不相关,但是如果(例如)有一个请求使启animation面消失,或者您想要使用BackgroundWorker,这将会很重要。

这些可以通过在启animation面中创build一个消息泵(通过调用ShowDialog()而不是Show()来模拟),但是在处理问题时处理症状确实并不困难。

在这种情况下,我强烈鼓励nobugz的回答 。 该框架提供了您所需要的支持。 尽pipeMicrosoft.VisualBasic命名空间中的function对于C#程序员来说并不总是很容易被发现,但它们可以成为像这样的情况下的真正的时间和救命稻草。

祝你好运!

你真的应该提供更多关于你的问题的细节。 我可能是完全错误的,但是我要在黑暗中一枪。 从我所想象的正在发生的事情出发,你想要显示启animation面,在另一个线程中做一些处理,然后在启animation面完成时离开。

为此,您需要将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()开始工作。

作为一个单独的说明,您似乎没有对传递给启animation面构造函数的ArrayList做任何事情。 这是打算?

不幸的是,我没有足够的声誉来评论某人的答案呢。 :(这是为了答复潘基文上校对汉斯·帕斯特答的评论 。

他的问题是new FormMain(args)显示的MessageBox将显示在启animation面的后面。 关键是从闪屏运行的线程调用MessageBox:

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

其中splashScreen是在OnCreateSplashScreen创build的启animation面对象的引用,显然必须赋予新的Form1对象。