在异步方法中显示进度对话框
Posted
技术标签:
【中文标题】在异步方法中显示进度对话框【英文标题】: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();
【问题讨论】:
【参考方案1】:在从 UI 线程调用的 async
方法中运行 UI 代码时(例如,像您在代码中一样的按钮单击等 UI 事件),您不需要使用 RunOnUiThread
。这是因为当 await
ed 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以上是关于在异步方法中显示进度对话框的主要内容,如果未能解决你的问题,请参考以下文章