我有一個按鈕和一個標籤WinForms應用程序以下代碼:訪問UI控件在Task.Run與異步/等待上的WinForms
using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
await Run();
}
private async Task Run()
{
await Task.Run(async() => {
await File.AppendText("temp.dat").WriteAsync("a");
label1.Text = "test";
});
}
}
}
這是實際應用I」的一個簡化的版本正在努力。我的印象是,通過在我的Task.Run
中使用async/await,我可以設置label1.Text
屬性。但是,運行此代碼時,我得到錯誤信息,說明我不在UI線程中,並且無法訪問該控件。
爲什麼我不能訪問標籤控件?
您不應該使用GUI同步上下文中的異步無效方法。 C.F. http://msdn.microsoft.com/en-us/magazine/jj991977.aspx - 「GUI和ASP.NET應用程序有一個SynchronizationContext,一次只允許運行一個代碼塊。當await完成時,它嘗試在捕獲的上下文中執行異步方法的其餘部分,但該上下文已經有一個線程,它正在(同步)等待異步方法完成,它們都在等待另一個,導致死鎖。 – Daniel
@Daniel這個引用是關於異步代碼的同步等待(例如'Wait()'),我當然不會這麼說。從同一篇文章:「無效返回異步方法有一個特定的目的:使異步事件處理程序成爲可能。」這正是我在這裏做的。 – svick
值得注意的是,任何未處理的私有異步任務運行()方法中發生的異常都會「冒泡」到異步事件處理程序本身。 – Jaans