我們有一個WinForm應用程序,它具有所有其他窗體繼承的基本窗體。
在基礎窗體上有一個Delete按鈕,Delete按鈕調用一個名爲DeleteData的虛擬bool方法。如何等待任務完成而WinForm中沒有死鎖,其中開發人員無法向當前方法添加異步
public virtual void DeleteButton_Click(object sender, EventArgs e)
{
if (DeleteData())
{
// run some cleanup code
DoSomeCleanup();
}
}
public virtual bool DeleteData()
{
throw new NotImplementedException("Not implemented.");
}
子窗體已經覆蓋了DeleteData方法
public override bool DeleteData()
{
try
{
// Delete some data
// Call async method that does some UI stuff and wait on it to finish
SomeSharedAsyncMethod();
return true;
}
catch(Exception ex)
{
// Handle exception
return false;
}
}
這裏是收集,SomeSharedAsyncMethod是標記爲異步和它裏面,它做了一些UI類的東西結合到文本框,並調用此方法別人因此該方法必須保持標記爲「異步」
public async Task SomeSharedAsyncMethod()
{
// Some code that has await and also some code that updates textboxes or other UI controls.
await Task.Delay(2000);
SomeTextBox.Text = "Some Text";
}
因爲基本形式看DeleteData我,我不能「異步」添加到「DeleteData」方法運行「DoSomeCleanup」和「DoSomeCleanup」將在DeleteData完成前調用。
我們還假設我無法將「異步」添加到刪除按鈕,因爲我沒有該項目的控制權。
我也不想重寫DeleteButton_Click,因爲我不想複製位於基本表單DeleteButton_Click內的所有代碼。
這裏有一些事情我已經嘗試:
public override bool DeleteData()
{
// Delete some data
// Call async method that does some UI stuff and wait on it to finish
// Causes a deadlock
SomeSharedAsyncMethod().Wait();
// RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.
SomeSharedAsyncMethod().RunSynchronously();
// This will not wait on SomeSharedAsyncMethod to execute
SomeSharedAsyncMethod().ConfigureAwait(false);
// Cross-thread operation not valid
Task.Run(async() => { await SomeSharedAsyncMethod(); }).Wait();
// This will not wait on SomeSharedAsyncMethod to execute
Task.Run(() => { SomeSharedAsyncMethod(); }).Wait();
// This will not wait on SomeSharedAsyncMethod to execute
Task.Run(async() => { await SomeSharedAsyncMethod().ConfigureAwait(false); }).Wait();
// This will not wait on SomeSharedAsyncMethod to execute
Task.Factory.StartNew(() =>
{
SomeSharedAsyncMethod().ConfigureAwait(false);
}, Task.Factory.CancellationToken, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()).Wait();
return true;
}
我們正在尋找獲得DeleteData方法來運行其所有的代碼,而不是返回,直到所有代碼行已完成的一種方式,這包括SomeSharedAsyncMethod 。
看着鎖:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement – Sorceri
檢查了這一點:https://stackoverflow.com/a/5097066/5779825。希望它有幫助 – oopsdazie