启动屏幕等待线程完成
我仍然遇到闪屏问题。 我不想使用属性 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++;
}
}
我想要的是在启动屏幕类中等待线程完成的东西。
如需了解更多详情,请告诉我需要告诉您的内容。
I still have a problem with the splash screen. I don't want to use the property SC.TopMost=true
.
Now my application scenario is as follows:
in progeram.cs:
[STAThread]
static void Main()
{
new SplashScreen(_tempAL);// where _tempAL is an arrayList
Application.Run(new Form1(_tempAL));
}
in SplashScreen class:
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++;
}
}
What I want is something in the splash screen class which waits until the thread finishes.
For more details, please tell me what I need to tell you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
同样的问题,同样的答案:
.NET 框架对闪屏具有出色的内置支持。 启动一个新的WF项目,Project + Add Reference,选择Microsoft.VisualBasic。 添加一个新表单,将其命名为 frmSplash。 打开 Project.cs 并使其看起来像这样:
Same question, same answer:
The .NET framework has excellent built-in support for splash screens. Start a new WF project, Project + Add Reference, select Microsoft.VisualBasic. Add a new form, call it frmSplash. Open Project.cs and make it look like this:
通过在调用 Application.Run() 之前创建 UI,您已经进入了危险区域。 Application.Run 本质上是程序的消息泵。 通过在启动应用程序的消息泵之前显示 UI,可以使典型的 UI 交互在过早的 UI 上实际上变得不可能。 对于闪屏来说,这可能看起来不相关,但如果(例如)有请求让闪屏在单击时消失,或者您想使用BackgroundWorker,那么这将很重要。
这些可以通过在启动屏幕中创建消息泵来解决(通过调用 ShowDialog() 而不是 Show() 使其成为模态),但这只是治疗症状,而治疗问题实际上并不那么困难。
在这种情况下,我强烈鼓励 nobugz 的回答。 该框架提供您所需的支持。 虽然 Microsoft.VisualBasic 命名空间中的功能并不总是很容易被 C# 程序员发现,但对于此类情况,它们确实可以节省时间和救星。
祝你好运!
You've entered dangerous territory by creating UI prior to your call to Application.Run(). Application.Run is essentially your program's message pump. By displaying the UI before you start the application's message pump, you make typical UI interaction effectively impossible on the premature UI. For a splash screen this may not seem relevant, but it will matter if (e.g.) there's a request to make the splash screen disappear if it's clicked on, or you want to use a BackgroundWorker.
These can be worked around by creating a message pump in your splash screen (by making it modal via a call to ShowDialog() instead of Show()), but that's treating the symptom when treating the problem really isn't that difficult.
I'd strongly encourage nobugz's answer in this case. The framework provides the support you need. While features in the Microsoft.VisualBasic namespace aren't always very discoverable to C# programmers, they can be a real timesaver and lifesaver for cases like this.
Good luck!
跨两个线程进行跟踪有点令人困惑,但我要尝试说一下......
我不完全理解您的设计,但如果问题是当您启动第二个应用程序时,启动屏幕形式变成白色...这很可能是由于启动屏幕正忙于执行 GetFromServer() 中的所有代码。 太忙了,以至于没有时间重新粉刷自己。
为了解决这个问题,我建议您使用 BackGroundWorker 组件执行 GetFromServer 方法。 这将在单独的线程中运行该方法,并让表单的线程自由地重新绘制自身。
Following across 2 threads is a bit confusing, but I'm going to take a stab and say this...
I don't fully understand your design here, but if the issue is that when you launch a second application the splash screen form turns white... It's most likely due to the fact that splash screen is busy executing all of that code in GetFromServer(). So busy that it has no time to re-paint itself.
To remedy this problem I would suggest that you use the BackGroundWorker component to execute the GetFromServer method. This will run that method in a separate thread and leave the form's thread free to re-paint itself.
不幸的是,我还没有足够的声誉来评论某人的答案。 :( 这意味着恐慌上校对汉斯·帕桑斯答案的评论< /a>
的问题是从
new FormMain(args)
显示的MessageBox
将显示在启动屏幕后面,关键是从线程中调用 MessageBox。启动画面运行于:其中
splashScreen
是对在OnCreateSplashScreen
中创建的启动画面对象的引用,显然必须将其提供给新的Form1对象。
Unfortunately I don't have enough reputation to comment on someones answer yet. :( This is meant to be the answer to Colonel Panics comment on Hans Passants answer.
His problem was that a
MessageBox
shown fromnew FormMain(args)
will be shown behind the splash screen. The key is to invoke the MessageBox from the thread the splash screen runs in:Where
splashScreen
is a reference to the splash screen object that has been created inOnCreateSplashScreen
and obviously has to be given to the newForm1
object.您确实应该提供有关您的问题的更多详细信息。 我可能完全错了,但我会在黑暗中尝试一下。 根据我的想象,您想要显示启动画面,在另一个线程中进行一些处理,然后启动画面在完成后消失。
为此,您需要将
GetFromServer()
调用移至BackgroundWorker
。 然后将代码移至
BackgroundWorker_RunWorkerCompleted
事件处理程序。要使用
BackgroundWorker
:1) 初始化
BackGroundWorker
2) 添加事件处理程序
3) 将代码添加到事件处理程序。
4) 调用
myWorker.RunWorkerAsync()
开始工作。作为一个单独的说明,您似乎没有对传递给初始屏幕构造函数的 ArrayList 执行任何操作。 这是故意的吗?
You really should give more details about your problem. I could be completely wrong, but I'm going to take a shot in the dark. From what I'm imagining is going on and you want, you want the splash screen to show, do some processing in another thread, then the splash screen to go away when finished.
To do this, you're going to want to move the
GetFromServer()
call to aBackgroundWorker
. Then move thecode to the
BackgroundWorker_RunWorkerCompleted
event handler.To use the
BackgroundWorker
:1) Initialize the
BackGroundWorker
2) Add event handlers
3) Add code to the event handlers.
4) Call
myWorker.RunWorkerAsync()
to start working.As a separate note, you don't seem to be doing anything with the
ArrayList
that you're passing to the splash screen's constructor. Is this intended?