【发布时间】:2011-01-21 10:53:56
【问题描述】:
我有一个带有 statusLabel 的 Windows 窗体 (C#.NET),我似乎无法在事件处理程序方法的进程中间进行更新。我的代码看起来像这样...
void Process_Completed(object sender, EventArgs e)
{
string t = "Process is finished!";
this.Invoke(new StatusLabelUpdator(updateStatusLabel), new object[] { t });
}
void Process_Started(object sender, EventArgs e)
{
string t = "Process has begun";
this.Invoke(new StatusLabelUpdator(updateStatusLabel), new object[] { t });
}
private delegate void StatusLabelUpdator(string text);
private void updateStatusLabel(string text)
{
StatusLabel1.Text = text;
statusStrip1.Invalidate();
statusStrip1.Refresh();
statusStrip1.Update();
}
当我运行代码时,一旦进程启动,就会触发 Process_Started 方法,几秒钟后会触发 Process_Completed 方法。由于某种原因,我无法让状态标签显示“进程已开始”。它只显示“过程已完成!”。如您所见,我已尝试使包含状态标签但未成功的状态条失效、刷新和更新。我不能在状态标签本身上调用更新/刷新/无效,因为这些方法对它不可用。我做错了什么?
添加信息:
“进程”是通过单击窗体上的按钮启动的,该窗体调用一个单独的类中的方法,如下所示:
public void DoSomeProcess()
{
TriggerProcessStarted();
System.Threading.Thread.Sleep(2000); // For testing..
TriggerProcessComplete();
}
在 TriggerProcessxxxx 方法中,我使用此代码触发事件...
var EventListeners = EH.GetInvocationList(); //EH is the appropriate EventHandler
if (EventListeners != null)
{
for (int index = 0; index < EventListeners.Count(); index++)
{
var methodToInvoke = (EventHandler)EventListeners[index];
methodToInvoke.BeginInvoke(this, EventArgs.Empty, EndAsyncEvent, new object[] { });
}
}
最后,我在updateStatusLabel 方法中添加了Application.DoEvents(),但它没有帮助。我仍然得到相同的结果。这是我的更新方法。
private void updateStatusLabel(string text)
{
StatusLabel1.Text = text;
statusStrip1.Refresh();
Application.DoEvents();
}
所以我猜“处理”发生在 UI 线程上,但事件处理程序在它自己的线程上被调用,然后在 UI 线程上调用控件更新。这是一种愚蠢的做事方式吗?注意:包含 DoSomeProcess() 方法的类位于我引用的单独 .NET ClassLibrary 中。
【问题讨论】: