Csharp/C#教程:异步ShowDialog分享


异步ShowDialog

我正在使用async / await从数据库异步加载我的数据,在加载过程中,我想弹出一个加载表单,它只是一个带有运行进度条的简单表单,表示有一个正在运行的进程。 加载数据后,对话框将自动关闭。 我怎样才能做到这一点? 以下是我目前的代码:

protected async void LoadData() { ProgressForm _progress = new ProgressForm(); _progress.ShowDialog() // not working var data = await GetData(); _progress.Close(); } 

更新:

我设法通过更改代码来使其工作:

  protected async void LoadData() { ProgressForm _progress = new ProgressForm(); _progress.BeginInvoke(new System.Action(()=>_progress.ShowDialog())); var data = await GetData(); _progress.Close(); } 

这是正确的方式还是有更好的方法?

谢谢你的帮助。

使用Task.Yield很容易实现,就像这样(WinForms,为简单起见,没有exception处理):

 namespace WinFormsApp { public partial class MainForm : Form { public MainForm() { InitializeComponent(); } async Task LoadDataAsync() { await Task.Delay(2000); return 42; } private async void button1_Click(object sender, EventArgs e) { var progressForm = new Form() { Width = 300, Height = 100, Text = "Please wait... " }; var progressFormTask = progressForm.ShowDialogAsync(); var data = await LoadDataAsync(); progressForm.Close(); await progressFormTask; MessageBox.Show(data.ToString()); } } internal static class DialogExt { public static async Task ShowDialogAsync(this Form @this) { await Task.Yield(); if (@this.IsDisposed) return DialogResult.OK; return @this.ShowDialog(); } } } 

重要的是要理解执行流如何跳转到新的嵌套消息循环(模式对话框的循环),然后返回到原始消息循环(这就是await progressFormTask的用途)。

这是一个使用Task.ContinueWith的表单,应该避免使用模态ProgressForm的任何竞争条件:

 protected async void LoadDataAsync() { ProgressForm _progress = new ProgressForm(); // 'await' long-running method by wrapping inside Task.Run await Task.Run(new Action(() => { // Display dialog modally // - Use BeginInvoke here to avoid blocking // and illegal cross threading exception this.BeginInvoke(new Action(() => { _progress.ShowDialog(); })); // Begin long-running method here LoadData(); })).ContinueWith(new Action(task => { // Close modal dialog // - No need to use BeginInvoke here // because ContinueWith was called with TaskScheduler.FromCurrentSynchronizationContext() _progress.Close(); }), TaskScheduler.FromCurrentSynchronizationContext()); } 

ShowDialog()是一个阻塞调用; 在用户关闭对话框之前,执行不会进入await语句。 请改用Show() 。 不幸的是,您的对话框不是模态的,但它将正确跟踪异步操作的进度。

您可以尝试以下方法:

上述就是C#学习教程:异步ShowDialog分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

 protected async void LoadData() { ProgressForm _progress = new ProgressForm(); var loadDataTask = GetData(); loadDataTask.ContinueWith(a => this.Invoke((MethodInvoker)delegate { _progress.Close(); })); _progress.ShowDialog(); } 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/1011864.html

(0)
上一篇 2021年12月29日
下一篇 2021年12月29日

精彩推荐