[英]Background worker RunWorkCompleted Event
我有以下wpf程序,我想做的是btnAnalyzer_click方法,直到兩個DoWork&RunWorkerCompleted方法都完成。 所以我使用了AutoResetEvent,但是現在bwAnalyze_click方法(#4行)在DoWork之后運行,然后在WorkerCompleted方法之后(行順序-#1#2#4&#3)運行。 但我希望它們按照#1#2#3&#4的順序執行。 有什么解決方案或建議嗎?
public partial class MainWindow : Window
{
private readonly BackgroundWorker bwAnalyzer = new BackgroundWorker();
private AutoResetEvent autoReset;//to signal the end of the BackgroudnWork
public MainWindow()
{
InitializeComponent();
autoReset = new AutoResetEvent(false);
bwAnalyzer.DoWork += new DoWorkEventHandler(DoWork);
bwAnalyzer.RunWorkerCompleted += new RunWorkerCompletedEventHandler(WorkerCompleted);
}
void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine("Completed"); #3
autoReset.Set();
}
void DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("load"); #2
}
private void btnAnalyze_Click(object sender, RoutedEventArgs e)
{
bwAnalyzer.RunWorkerAsync(); #1
autoReset.WaitOne();//when commented working properly
Console.WriteLine("click"); #4
}
}
雖然建議使用“任務”的答案會起作用,但對於為什么要等到后台工作人員完成其工作之后再讓UI線程的click事件繼續,我有些困惑。 據我了解,您使用后台工作程序是因為您要執行后台工作而不阻塞UI。 您提出問題的方式表明您想在完成工作之前阻止UI。 在這種情況下,為什么還要使用單獨的線程?
另外,關於您的評論:
autoReset.WaitOne();//when commented working properly
我假設如果不加注釋,則UI會永久阻塞? 當您在按鈕的click事件中調用autoReset.WaitOne()
時,您正在阻塞UI線程。 盡管DoWork
將在后台線程上運行,但RunWorkerCompleted
事件在UI線程上運行。 因此RunWorkerCompleted將永遠無法執行。
如果您評論WaitOne()
調用,我認為它根本不會“正確”地工作。 我對其進行了測試,由於UI線程和后台線程之間存在競爭,因此它在click-> load-> completed和load-> click-> completed之間有所不同。
使用任務,並使用ContinueWith方法: https : //msdn.microsoft.com/zh-cn/library/dd270696(v=vs.110).aspx
我想以下應該給出所需的行為-
private void btnAnalyze_Click(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() => {
})
.ContinueWith(f => {
})
.Wait();
}
這里的大多數答案正確地要求您嘗試使用TPL進行操作,但是,如果您遇到的復雜情況是需要使用ManualResetEvent / AutoResetEvent,那么這里就是您解決問題的方法。 只需將btn click邏輯包含在“任務”或線程中即可。 想法是您不想保留UI(STA Main)線程。 這導致某些運行時優化,並導致不良行為。
Task.Factory.StartNew(() =>
{
bwAnalyzer.RunWorkerAsync(); //#1
autoReset.WaitOne(); //when commented working properly
Console.WriteLine("click"); //#4
});
上面的代碼片段應該給您想要的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.