在按钮点击期间等待异步任务是否可能?

17

我的应用有一个刷新按钮,使用一些异步方法来更新显示的项目列表。问题在于我无法为按钮点击的事件处理程序设置Task类型的返回值,所以只能使用async void方法。因此,用户可以在列表重新填充时点击刷新按钮,然后选择一个项目,这将导致错误。

处理按钮点击的代码开始:

    private async void Button_Click_1(object sender, RoutedEventArgs e)
    {


        await ViewModel.CreateMessageCommand();

那么有没有办法正确等待这个任务完成呢?

3个回答

25

由于控件的事件处理程序通常返回void,因此您需要以不同的方式处理它。在像您这样的情况下,这通常意味着您需要在加载过程中禁用所有或部分UI,例如:

private async void Button_Click_1(object sender, RoutedEventArgs e)
{
    // Make the "list" disabled, so the user can't "select an item" and cause an error, etc
    DisableUI();

    try
    {    
       // Run your operation asynchronously
       await ViewModel.CreateMessageCommand();
    }
    finally
    {
       EnableUI(); // Re-enable everything after the above completes
    }
}

2

在操作开始时,您应该禁用用户不应交互的所有UI控件,然后在操作结束时启用它们。


1

一种方法是将视图包装在WPF Toolkit的BusyIndicator中。

您可以在您的视图模型上提供一个布尔属性,在开始和结束时切换该值。

它会在所有其他控件上方放置一个UI元素,防止用户交互但提供一个动画的繁忙消息,该消息可以更新为任何您希望的内容。


我不知道为什么它不应该。除非他们限制你可以使用哪些第三方库。 - ywm
2
您不能在 Windows Store 应用程序中使用 WPF 控件。虽然仍然使用 Xaml,但这是不同的平台。您需要一个第三方繁忙指示器端口(或编写自己的代码) 。 - Reed Copsey
@ReedCopsey 既然是开源的,你可以下载源代码并为正确的平台重新编译。或者只拿取相关的BusyIndicator控件。 - ywm
@ywm 很不幸,从WPF迁移到Windows Store通常不仅仅是重新编译。Windows Store API比WPF的功能要少得多,因此根据控件中使用的内容,可能会很困难。来自Silverlight Toolkit的版本可能是一个更简单的移植:https://silverlight.codeplex.com/SourceControl/latest#Release/Silverlight4/Source/Controls.Toolkit/BusyIndicator/BusyIndicator.xaml - Reed Copsey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接