3 回答

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超7個(gè)贊
如果我了解您的要求正確,則可以執(zhí)行以下操作(代碼未經(jīng)測(cè)試,但顯示了總體思路):
private BackgroundWorker worker = new BackgroundWorker();
private AutoResetEvent _resetEvent = new AutoResetEvent(false);
public Form1()
{
InitializeComponent();
worker.DoWork += worker_DoWork;
}
public void Cancel()
{
worker.CancelAsync();
_resetEvent.WaitOne(); // will block until _resetEvent.Set() call made
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
while(!e.Cancel)
{
// do something
}
_resetEvent.Set(); // signal that worker is done
}

TA貢獻(xiàn)1878條經(jīng)驗(yàn) 獲得超4個(gè)贊
此響應(yīng)有問(wèn)題。UI需要在您等待時(shí)繼續(xù)處理消息,否則它將不會(huì)重新繪制,如果后臺(tái)工作人員花很長(zhǎng)時(shí)間來(lái)響應(yīng)取消請(qǐng)求,這將是一個(gè)問(wèn)題。
第二個(gè)缺陷是,_resetEvent.Set()如果工作線程引發(fā)異常-將使主線程無(wú)限期地等待-將永遠(yuǎn)不會(huì)被調(diào)用-但是,可以使用try / finally塊輕松修復(fù)此缺陷。
一種方法是顯示一個(gè)模態(tài)對(duì)話框,其中包含一個(gè)計(jì)時(shí)器,該計(jì)時(shí)器可反復(fù)檢查后臺(tái)工作人員是否已完成工作(或在您的情況下完成取消)。后臺(tái)工作人員完成操作后,模態(tài)對(duì)話框?qū)⒖刂茩?quán)返回給您的應(yīng)用程序。在這種情況發(fā)生之前,用戶無(wú)法與UI進(jìn)行交互。
另一種方法(假設(shè)您最多打開(kāi)一個(gè)無(wú)模式窗口)是設(shè)置ActiveForm.Enabled = false,然后在Application,DoEvents上循環(huán),直到后臺(tái)工作程序完成取消為止,然后可以再次設(shè)置ActiveForm.Enabled = true。

TA貢獻(xiàn)1875條經(jīng)驗(yàn) 獲得超3個(gè)贊
幾乎所有人都對(duì)這個(gè)問(wèn)題感到困惑,并且不了解如何使用工人。
考慮一個(gè)RunWorkerComplete事件處理程序:
private void OnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (!e.Cancelled)
{
rocketOnPad = false;
label1.Text = "Rocket launch complete.";
}
else
{
rocketOnPad = true;
label1.Text = "Rocket launch aborted.";
}
worker = null;
}
一切都很好。
現(xiàn)在出現(xiàn)了這樣一種情況,即呼叫者需要中止倒計(jì)時(shí),因?yàn)樗麄冃枰獔?zhí)行火箭的緊急自毀。
private void BlowUpRocket()
{
if (worker != null)
{
worker.CancelAsync();
WaitForWorkerToFinish(worker);
worker = null;
}
StartClaxon();
SelfDestruct();
}
還有一種情況,我們需要打開(kāi)火箭的檢修門(mén),而不是在倒計(jì)時(shí)時(shí):
private void OpenAccessGates()
{
if (worker != null)
{
worker.CancelAsync();
WaitForWorkerToFinish(worker);
worker = null;
}
if (!rocketOnPad)
DisengageAllGateLatches();
}
最后,我們需要給火箭加油,但是在倒數(shù)計(jì)時(shí)中這是不允許的:
private void DrainRocket()
{
if (worker != null)
{
worker.CancelAsync();
WaitForWorkerToFinish(worker);
worker = null;
}
if (rocketOnPad)
OpenFuelValves();
}
沒(méi)有等待工人取消的能力,我們必須將所有三個(gè)方法移至RunWorkerCompletedEvent:
private void OnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (!e.Cancelled)
{
rocketOnPad = false;
label1.Text = "Rocket launch complete.";
}
else
{
rocketOnPad = true;
label1.Text = "Rocket launch aborted.";
}
worker = null;
if (delayedBlowUpRocket)
BlowUpRocket();
else if (delayedOpenAccessGates)
OpenAccessGates();
else if (delayedDrainRocket)
DrainRocket();
}
private void BlowUpRocket()
{
if (worker != null)
{
delayedBlowUpRocket = true;
worker.CancelAsync();
return;
}
StartClaxon();
SelfDestruct();
}
private void OpenAccessGates()
{
if (worker != null)
{
delayedOpenAccessGates = true;
worker.CancelAsync();
return;
}
if (!rocketOnPad)
DisengageAllGateLatches();
}
private void DrainRocket()
{
if (worker != null)
{
delayedDrainRocket = true;
worker.CancelAsync();
return;
}
if (rocketOnPad)
OpenFuelValves();
}
現(xiàn)在,我可以這樣編寫(xiě)代碼,但是我不會(huì)。我不在乎,我只是不在乎。
- 3 回答
- 0 關(guān)注
- 495 瀏覽
添加回答
舉報(bào)