[英]Continue code execution after calling ShowDialog()
我試圖在 else 代碼在后台繼續執行時打開一個加載窗口,並在需要時關閉它(無線程)。
像這樣的東西:
LoadingWindow.ShowDialog();
Thread.Sleep(2000); //Simulates slowness
AnotherForm.ShowDialog();
LoadingWindow.Close(); //After AnotherForm displayed.
我不能只使用LoadingWindow.Show();
繼續執行,因為 LoadingWindow 將無法正確顯示,直到LoadingWindow.Show();
之后的代碼LoadingWindow.Show();
被執行。
我有一個自定義的 Async ShowDialog 方法ShowDialogAsync();
,但問題是 await 直到AnotherForm.ShowDialog();
才會到達AnotherForm.ShowDialog();
完成。
我試過了:
var LoadingTask = LoadingWindow.ShowDialogAsync();
Thread.Sleep(2000); //Simulates slowness
//await AnotherForm.ShowDialogAsync(); //Not worked
//AnotherForm.ShowDialog(); //Not worked
//AnotherForm.Show(); //Not Worked
LoadingWindow.Close();
await LoadingTask;
這只能與 await 一起用於簡單的方法:
var LoadingTask = LoadingWindow.ShowDialogAsync();
var data = await LoadDataAsync();
LoadingWindow.Close();
await LoadingTask;
//Sample simple method
private void LoadDataAsync()
{
await Task.Delay(2000);
return 10;
}
ShowDialogAsync:
public static async Task<DialogResult> ShowDialogAsync(this Form @this)
{
await Task.Yield();
if (@this.IsDisposed)
return DialogResult.OK;
return @this.ShowDialog();
}
作為鏈接答案的作者,我感到被召喚:) 我想我理解您遇到的問題。 嘗試以下操作,查看內聯注釋:
// on the main message loop of the UI thread
var LoadingTask = LoadingWindow.ShowDialogAsync();
// dialog isn't shown here yet, yield to the message loop
await Task.Yield();
// now ShowDialog has been called and the dialog is visible,
// we're now on the nested message loop run by ShowDialog
await Task.Run(() =>
{
// on a thread pool thread, do the work here
Thread.Sleep(2000);
});
// on the UI thread, still on the nested message loop of ShowDialog
// close the dialog
LoadingWindow.Close();
// still on the nested message loop, despite the window has closed
await LoadingTask;
// this is when ShowDialog method has returned,
// and we're back to the main message loop of the UI thread
不要在 UI 線程上使用Thread.Sleep
或任何其他長時間運行的同步代碼,即使是在實驗中。 該對話框是異步顯示的。 Thread.Sleep
阻塞消息循環,並且ShowDialog
沒有機會在您期望的時候執行。
在這種情況下,它有助於理解Task.Yield
在Task.Yield
背后實際做了什么。 await Task.Yield()
之后的繼續代碼直到消息循環的一些未來迭代之后才會神奇地執行。 當您在 UI 線程上進行阻塞調用時,將不會有未來的迭代。 這就是線程池和Task.Run
的用途。
否則,繼續回調將位於由WindowsFormsSynchronizationContext
或DispatcherSynchronizationContext
管理的隊列中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.