我的表單上有很長的用戶界面操作,每當觸發事件時都會觸發該操作。在操作發生時,我不想讓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();
}
,而不必我的表格上禁用跨線程檢查?理想情況下,我希望能夠在線程或方法中設置一些屬性,這些屬性單獨包裝了代表中的所有操作,然後在表單的線程中調用該委託。
所以要取消線程,我可以再次調用operation.Post()與拋出異常的委託函數?或者會等到第一次操作.Post()完成了嗎? – Simon 2008-11-20 08:58:31
...或將PostOperationCompleted中止操作? – Simon 2008-11-20 09:19:00
它不會中止,它只會完成異步操作。我認爲你甚至可以忽略它。另一種方法是不使用AsyncOperationManager,但它被認爲更好: SynchronizationContext syncContext; this.syncContext = SynchronizationContext.Current; this.syncContext.Post(delegate {},null) – netadictos 2008-11-20 10:35:05