【问题标题】:showing progress Dialog inside an async method在异步方法中显示进度对话框
【发布时间】:2016-11-11 19:35:43
【问题描述】:

我想在异步事件侦听器方法中显示进度对话框。现在,UI 组件仅在异步方法执行完成后才可见。这是我的代码:

async void process_Click(object sender, EventArgs e)
    {

        launchRingProgressDialog();

        var comp = await Start();

    }

public void launchRingProgressDialog()
    {
        Activity.RunOnUiThread(() =>
        {
            ProgressDialog ringProgressDialog = ProgressDialog.Show(Activity, "Processing", "Please wait", true);
            ringProgressDialog.SetCancelable(true);
        });
    }

当我在异步方法之外调用方法launchRingProgressDialog()时显示进度对话框,但在异步方法运行时不显示。如何使异步方法不阻塞 UI 组件?

编辑

据我了解,异步方法在 UI 线程内运行,因此不需要 RunOnUiThread。我已将代码更改如下,但我仍然面临同样的问题。

 async void process_Click(object sender, EventArgs e)
    {

        ringProgressDialog = ProgressDialog.Show(Activity, "Processing", "Please wait", true);

        var comp = await Start();

        ringProgressDialog.Dismiss();

        }

【问题讨论】:

    标签: c# android asynchronous


    【解决方案1】:

    在从 UI 线程调用的 async 方法中运行 UI 代码时(例如,像您在代码中一样的按钮单击等 UI 事件),您不需要使用 RunOnUiThread。这是因为当 awaited Task 完成时,方法会在调用线程上继续,在本例中是 UI 线程。

    例如,看看下面的代码,它是我的一个应用程序的一部分,它成功运行并获得了预期的结果:

    private async void ExecuteSearchButton_Click(object sender, System.EventArgs e)
    {
        spinner.Visibility = ViewStates.Visible;
    
        CollectionFeed feed = await CollectionFeed.SearchAsync(searchEditText.Text);
    
        GenericAdapter<Collection, CollectionViewHolder> adapter = 
                new GenericAdapter<Collection, CollectionViewHolder>(Resource.Layout.CollectionRecyclerViewItem,
                                                                     feed.Results, view => new CollectionViewHolder(view));
    
        searchResultRecyclerView.SetAdapter(adapter);
    
        spinner.Visibility = ViewStates.Gone;
    }
    

    spinner 在点击时出现,在数据加载到 RecyclerView.Adapter(也成功加载)时消失。

    您编辑的方法将是

    public void launchRingProgressDialog()
    {
        ProgressDialog ringProgressDialog = ProgressDialog.Show(Activity, "Processing", "Please wait", true, true);
    }
    

    它使用this ProgressDialog constructor 删除SetCancelable 调用。

    【讨论】:

    • 我知道异步方法在 UI 线程中运行,我不需要 RunOnUiThread。我在异步操作运行之前启动对话框并在等待任务之后将其关闭,但这并没有真正起作用。只有在整个异步方法执行完毕后,对话框或任何其他 UI 组件才可见。也许我应该在异步方法中启动一个新线程并在其中运行异步操作?
    • @AhmedMujtaba 如果我修改我作为示例发布的代码以包含ProgressDialog,它会在正确的时间出现并被取消。您的async 操作是否持续时间很短(async 方法时,Xamarin 会导致应用程序出现小暂停。
    • 我已经通过在 Task.Run 中运行异步操作来解决它。我还有一个小问题需要解决。我想在第一个对话框被关闭后启动一个新的 ProgressDiaglog,但第二个对话框仅在异步方法执行完成后才显示。这是因为 UI 线程上的活动过多,它会阻塞其他 UI 操作吗?
    • 您的异步方法实际上是异步的(即它们有一个await 或返回一个可运行的Task)还是为了异步而使用async?如果他们真的是async,那么应该没有任何东西阻塞 UI 线程。
    • 我有 2 个异步方法,当按下按钮时调用它,另一个在单独的线程中运行进程。你可以从这里查看我的完整代码pastie.org/10902657
    猜你喜欢
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多