[英]UI is unresponsive in winforms when using async methods
所以我有幾個方法想在我的表單加載時調用(最好在構造函數中調用,但由於 async/await 在構造函數中不起作用,我正在使用Form_Load
事件)。 最初我使用一個單獨的線程來完成這項工作,效果很好。 一切都已完成,並且在工作完成時 UI 是響應式的。 但是,我讀到使用 async/await 是“更好”、“資源密集度較低”,並且通常比創建單獨的線程更受歡迎。 我猜原因是使用 async/await 使用的線程更少?
但是當我如下圖所示使用此方法時,UI 被凍結/無響應,而 function 正在運行需要幾秒鍾。
在我的Form_Load
事件中,我調用了一個同步方法:
private void Form_Load(object sender, EventArgs e)
{
CheckForDriver();
}
然后這是我的CheckForDriver
function:
private void CheckForDriver()
{
System.Management.SelectQuery query = new SelectQuery("Win32_SystemDriver") {
Condition = "Description = 'my driver'" };
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection drivers = searcher.Get();
if (drivers.Count > 0) // valid driver, go to next page
{
wizardControl.SelectedTab = startPage;
task = QueryDeviceAsync(false, new List<Button>());
}
}
其中task
是定義為private Task task;
這里是QueryDeviceAsync
function,需要一些時間的部分是switcher.GetDeviceAndSize()
function。
private async Task QueryDeviceAsync(bool enableForm, List<Button> buttons)
{
lastBackEnable = backBtn.Enabled;
lastNextEnable = nextBtn.Enabled;
EnableButtons(false, false);
this.Enabled = enableForm;
if (buttons != null)
{
foreach (Button button in buttons)
{
button.Enabled = false;
}
}
await Task.Run(() => switcher.GetDeviceAndSize()); // this function takes a few seconds and this is where the UI becomes unresponsive.
ThreadFinished?.Invoke(buttons);
}
然后在ThreadFinished
事件處理程序中,我正在執行await task;
等待QueryDeviceAsync
function 完成,此時我根據switcher.GetDeviceAndSize
function 所做的更新一些 UI 內容。 我也對我是否可以/應該以異步方法更新 UI 內容感到困惑,例如當我禁用QueryDeviceAsync
function 中buttons
列表中的按鈕時。我知道這在第二個線程中不起作用,必須是在創建它們的線程上完成,但這運行沒有問題。
我的主要問題是當我使用這些異步函數時表單仍然沒有響應。 當我使用單獨的線程時它工作正常,所以我傾向於 go 回到那個,但我想我會嘗試找出這個方法。
在這種情況下,您需要將阻塞的同步工作卸載到工作線程。 例如:
var search = new ManagementObjectSearcher(Query.ToString());
await Task.Run(() => search.Get());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.