【发布时间】:2008-11-19 14:46:32
【问题描述】:
我的表单上有一个冗长的用户界面操作,只要触发事件就会触发。我不想在操作发生时阻止 UI,而是想在另一个线程中执行操作,并中止该线程并在事件再次触发时重新开始。
但是,为了安全地更改表单上的控件,我需要使用表单的 Invoke 或 BeginInvoke 方法。如果我这样做,那么我可以将所有 UI 操作放在一个函数中,如下所示:
private delegate void DoUIStuffDelegate(Thing1 arg1, Thing2 arg2);
private void doUIStuff(Thing1 arg1, Thing2 arg2)
{
control1.Visible = false;
this.Controls.Add(arg1.ToButton());
...
control100.Text = arg2.ToString();
}
...
private void backgroundThread()
{
Thing1 arg1 = new Thing1();
Thing2 arg2 = new Thing2();
this.Invoke(new DoUIStuffDelegate(doUIStuff), arg1, arg2);
}
Thread uiStuffThread = null;
public void OnEventFired()
{
if (uiStuffThread != null)
uiStuffThread.Abort();
uiStuffThread = new Thread(backgroundThread);
uiStuffThread.Start();
}
但如果我这样做,那么我将失去在单独线程中工作的好处。或者,我可以将它们分别放在自己的函数中,如下所示:
private delegate void DoUIStuffLine1Delegate();
private delegate void DoUIStuffLine2Delegate(Thing1 arg1);
...
private delegate void DoUIStuffLine100Delegate(Thing2 arg2);
private void doUIStuffLine1()
{
control1.Visible = false;
}
private void doUIStuffLine2()
{
this.Controls.Add(arg1.ToButton());
}
...
private void doUIStuffLine100(Thing2 arg2)
{
control100.Text = arg2.ToString();
}
...
private void backgroundThread()
{
Thing1 arg1 = new Thing1();
Thing2 arg2 = new Thing2();
this.Invoke(new DoUIStuffLine1Delegate(doUIStuffLine1));
this.Invoke(new DoUIStuffLine2Delegate(doUIStuffLine2), arg1);
...
this.Invoke(new DoUIStuffLine100Delegate(doUIStuffLine100), arg2);
}
Thread uiStuffThread = null;
public void OnEventFired()
{
if (uiStuffThread != null)
uiStuffThread.Abort();
uiStuffThread = new Thread(backgroundThread);
uiStuffThread.Start();
}
但这是一个可怕的、无法维护的混乱局面。有没有办法创建一个可以修改用户界面并且我可以中止的线程?这样我就可以这样做:
private void doUIStuff()
{
Thing1 arg1 = new Thing1();
Thing2 arg2 = new Thing2();
control1.Visible = false;
this.Controls.Add(arg1.ToButton());
...
control100.Text = arg2.ToString();
}
Thread uiStuffThread = null;
public void OnEventFired()
{
if (uiStuffThread != null)
uiStuffThread.Abort();
uiStuffThread = this.GetNiceThread(doUIStuff);
uiStuffThread.Start();
}
不必在我的表单上禁用跨线程检查?理想情况下,我希望能够在线程或方法上设置一些属性,将所有操作单独包装在委托中,然后在表单的线程上调用。
【问题讨论】:
标签: c# .net user-interface multithreading