无法使用异步等待方法显示进度对话框

Posted

技术标签:

【中文标题】无法使用异步等待方法显示进度对话框【英文标题】:can't get progressdialog to show with async await method 【发布时间】:2013-10-22 02:13:22 【问题描述】:

我正在尝试在应用程序保存到数据库时显示进度对话框。我想使用 async await 关键字来做到这一点,但我无法显示进度对话框。我是否必须为此添加一些在 ui 线程上运行的语法?在我的按钮 onclick 事件上向异步方法添加进度对话框的最简单最简洁的方法是什么?

protected override void OnCreate (Bundle bundle)

    base.OnCreate (bundle);
    SetContentView (Resource.Layout.Main);

    Button button_submit = FindViewById<Button> (Resource.Id.button_submit);

    button_submit.Click += async (object sender, EventArgs e) =>  
        using (ProgressDialog progressDialog = ProgressDialog.Show (this, "Please wait...", "Saving Data", true))
        
            try
            
                await this.SaveData();
            
            finally
                progressDialog.Dismiss();
            
        


    ;

这里是 SaveData 方法

private async Task<bool> SaveData()


    try
        //Validate ();

        string connectionString = "Foo"

        SqlConnection dbcon;
        using (dbcon = new SqlConnection(connectionString)) 

            await dbcon.OpenAsync();
            using (SqlCommand dbcmd = dbcon.CreateCommand()) 

                //MERGE UPSERT
                string sql = "bar"

                dbcmd.CommandText = sql;
                dbcmd.Parameters.AddWithValue("@id", this.scanId);

                dbcmd.Parameters.AddWithValue ("@lat", this.geo[0]); 
                dbcmd.Parameters.AddWithValue ("@lng", this.geo[1]);
                dbcmd.Parameters.AddWithValue ("@timestamp", this.timestamp);
                      //commented out to test to make sure slow file io isn't the issue
                //byte[] imageBytes = System.IO.File.ReadAllBytes (photoUri.Path);
                //dbcmd.Parameters.AddWithValue ("@photo", imageBytes);

                var result = await dbcmd.ExecuteNonQueryAsync();

                if (result != 1)
                    throw new Exception("Save encountered an error " + result);
            
        
        //ResetData ();
        RunOnUiThread(() => Toast.MakeText (this, "Data Saved", ToastLength.Long).Show ());
        return true;
    
    catch (Exception ex) 
        RunOnUiThread(() => Toast.MakeText (this, ex.Message, ToastLength.Long).Show ());
        return false;
    




【问题讨论】:

如果将 await this.SaveData() 替换为 await Task.Run(() =&gt; SaveData()),您的原始代码会如何表现? 让进度正确显示,但在 Dismiss() 方法上出现错误“无法在未调用 Looper.prepare() 的线程内创建处理程序” 由于Task.Run 确实显示了进度,这表明SaveData 实际上并不是异步的(正如@Servy 评论的那样)。你的问题在SaveData 我看到错误来自不在 RunOnUiThread 中的吐司,我刚刚包装了它,看起来进度对话框显示正确。将尝试删除现在运行的任务并查看。 @MonkeyBonkey 您正在同步读取整个文件的内容。这可能非常耗时。它应该异步完成。 【参考方案1】:

试试这个内部按钮点击..这很简单

ProgressDialog progress = new ProgressDialog(this);
progress.Indeterminate = true;
progress.SetProgressStyle(ProgressDialogStyle.Spinner);
progress.SetMessage("Loading... Please wait...");
progress.SetCancelable(false);

RunOnUiThread(() =>

    progress.Show();
);
Task.Run(()=>
//here savedata method
).ContinueWith(Result=>RunOnUiThread(()=>progress.Hide()));

【讨论】:

以上是关于无法使用异步等待方法显示进度对话框的主要内容,如果未能解决你的问题,请参考以下文章

如何关闭带有异步任务的进度对话框并避免“您的活动是不是运行错误?”

等待对话框实现

等待 Dart 异步函数完成

如果异步任务被解除,则重新显示进度对话框

C# Winform 多线程异步委托进度条

在异步任务中给出异常的进度对话框[重复]