WPF异步属性最佳实践 [英] WPF Best practice for async property

查看:200
本文介绍了WPF异步属性最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个运行很长时间的Web API调用(异步方法),它返回一个字符串.

Let's suppose I have a long running Web API call (async method) which returns a string.

在这两种解决方案之间是否存在最佳实践,以便在WPF属性中显示结果而不阻塞UI?还是还有另一个?

Is there a best practice between those 2 solutions to display the result in a WPF property without blocking UI ? Or is there another one ?

注意:两种解决方案都不会冻结UI,并且我已经查看了帖子 c#中的异步属性.

Note: both solutions are not freezing UI and I already view posts How to call an async method from a getter or setter? and Async property in c#.

private async Task<string> GetAsyncProperty()
{
    string result = "Async Property Value";

    // Web api call...
    await Task.Delay(TimeSpan.FromSeconds(10));

    return result;
}

解决方案A

XAML:

Solution A

XAML:

<TextBlock Text="{Binding Path=AsyncPropertyA, UpdateSourceTrigger=PropertyChanged}" />

ViewModel:

ViewModel:

public MyConstructor()
{
    Task task = SetAsyncPropertyA();
}

private async Task SetAsyncPropertyA()
{
    this.AsyncPropertyA = await GetAsyncProperty().ConfigureAwait(false);
}

解决方案B

XAML:

Solution B

XAML:

<TextBlock Text="{Binding Path=AsyncPropertyB, UpdateSourceTrigger=PropertyChanged, IsAsync=True, FallbackValue='Loading B...'}" />

ViewModel:

ViewModel:

public string AsyncPropertyB
{
    get
    {
        return GetAsyncPropertyB();
    }
}

private string GetAsyncPropertyB()
{
    return Task.Run(() => GetAsyncProperty()).Result;
}

注意:在解决方案B中,我可以在Task.Run的ContinueWith中添加在解决方案A中不起作用的FallbackValue和可能的其他一些UI更新.

Note: in solution B, I can add FallbackValue that's not working in solution A and potentially some other UI updates in ContinueWith of the Task.Run.

推荐答案

在两种情况下,您都不会捕获尝试调用Web API时可能发生的任何错误.您可能想要将其记录到文件中和/或向用户显示错误消息.

In both cases, you're not catching any errors that might happen while trying to call the Web API. You might want to log it to a file and/or show an error message to the user.

在这种情况下,等待很容易-您可以使用try/catch:

In that case, await makes it easy - you can just use try/catch:

public MyConstructor()
{
    try
    {
        Task task = SetAsyncPropertyA();
    }
    catch (Exception e)
    {
        // log the error or show a message
    }
}

private async Task SetAsyncPropertyA()
{
    this.AsyncPropertyA = await GetAsyncProperty().ConfigureAwait(false);
}

您还可以将try/catch移到async方法.在这种情况下,由于没有机会逃脱错误,因此可以使它异步无效.有时,这对于事件处理程序是必要的(至少在Windows窗体中-不确定WPF.)

You could also move the try/catch to the async method. In that case, since there's no chance of an error escaping from it, you could make it async void. Sometimes this is necessary for event handlers (at least in Windows Forms - not sure about WPF.)

public MyConstructor()
{
    SetAsyncPropertyA();
}

private async void SetAsyncPropertyA()
{
    try
    {
        this.AsyncPropertyA = await GetAsyncProperty().ConfigureAwait(false);
    }
    catch (Exception e)
    {
        // log the error or show a message
    }
}

这篇关于WPF异步属性最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆