下面的代碼是我遇到的問題的簡單示例。在表單加載時會發生什麼 - For循環會在每次迭代中創建一個新任務,然後進入'if(pic.InvokeRequired)'部分,但會返回到For循環並繼續迭代在調用pic.BeginInvoke()之後,任務會經過它們各自對method()的調用。如何正確地等待任務使用多線程完成調用?
我想實現的是調用完成它的第二遍方法()並最終將pic.BackColor更改爲Color.Blue。我想這是可能的,不是嗎?我花了幾個小時尋找並找不到滿意的答案。
要自己運行此代碼,請創建一個新的WinForms應用程序項目(我正在使用Visual Studio 2012)並添加一個PictureBox叫做'pic'。插入下面的代碼。
謝謝你的幫助!
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 5; i++)
{
Task task = Task.Factory.StartNew(() => method());
task.Wait(); //Waits for task to complete before proceeding
}
}
public delegate void delegate_method();
private void method()
{
if (pic.InvokeRequired)
{
delegate_method dm = new delegate_method(() => method());
pic.BeginInvoke(dm); //If ran once (without the loop in Form1_Load) it would call 'method()' immediately from here.
}
else
{
pic.BackColor = Color.Blue;
}
}
改爲使用Form.Activated事件。 – thepirat000
仍然與交叉線程衝突。如果合併Form.Activate事件爲您工作,您可以發佈我的示例的修改嗎? – user3034748
我正在閱讀這個問題的方式是,當你等待一個異步調用完成時,你想要做的就是阻塞。唯一能夠做到這一點的方法(至少我能在這種情況下看到的唯一方式)是用'while(!task.IsCompleted)Application.DoEvents()替換你的'task.Wait() );''和'pic.BeginInvoke(dm);''pic.Invoke(dm);',由於Application.DoEvents()的惡意特性,我絕對不建議這樣做。相反,你應該看看如何讓你的代碼正確地調用'method()',以避免阻塞(即task.Wait()))。 –