[英]Winforms await async/await Task never returns
我有一個Winforms exe,並從菜單中啟動了運行緩慢的進程作為“任務”。 大約需要30秒才能獲取數據,然后顯示一個對話框。 通常它不再返回。 我捕獲到異常,並且日志中沒有任何內容,因此我知道它運行正常。 該表格永遠不會出現,並且似乎不會占用任何CPU時間。 但是我在調試器中運行它並逐步執行代碼,它運行良好。 有時候,它似乎確實可以在速度更快的PC上運行。 怎么了?
private async void inPlayRecordToolStripMenuItem_Click(object sender, EventArgs e)
{
if (!GetClient()) return;
{
await Task.Run(() =>
{
LaunchForm();
});
}
}
private async void LaunchForm()
{
try
{
{
var inPlayView = new InPlayView();
await inPlayView.GetData();
inPlayView.ShowDialog();
}
}
catch (Exception ex)
{
Logger.LogMessage(ex.ToString());
}
}
改為這樣做:
private async void inPlayRecordToolStripMenuItem_Click(object sender, EventArgs e)
{
if (!GetClient()) return;
await LaunchForm();
}
private async Task LaunchForm()
{
try
{
var inPlayView = new InPlayView();
await inPlayView.GetData();
inPlayView.ShowDialog();
}
catch (Exception ex)
{
Logger.LogMessage(ex.ToString());
}
}
你不想Task.Run()
為已異步方法,並作為一般規則, async void
是好的只有事件處理程序,所以不是LaunchForm()
方法。
另外,正如注釋所指出的那樣, Task.Run()
將任務排隊到ThreadPool中,因此它將最終脫離UI線程。
我在其中一個項目上使用了async / await,我想不出在任務中執行ShowDialog
的原因。 不知道這是否行得通,但您可能需要稍微改變一下流程。 這應該使其更加一致,並且可能更易於調試。
private async void inPlayRecordToolStripMenuItem_Click(object sender, EventArgs e) {
if (!GetClient()) {
return;
}
var playView = await LaunchForm();
if (playView != null) {
playView.ShowDialog();
}
}
private async Task<InPlayView> LaunchForm() {
try {
var inPlayView = new InPlayView();
await inPlayView.GetData();
return inPlayView;
} catch (Exception ex) {
// do cleanup of view if needed
Logger.LogMessage(ex.ToString());
return null;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.