C# WPF异步属性的最佳实践

C# WPF异步属性的最佳实践,c#,wpf,asynchronous,data-binding,async-await,C#,Wpf,Asynchronous,Data Binding,Async Await,假设我有一个长时间运行的Web API调用(异步方法),它返回一个字符串 这两种解决方案之间是否有一种最佳做法,可以在WPF属性中显示结果而不阻塞UI?或者还有别的吗 注意:这两种解决方案都不是冻结用户界面,我已经查看了帖子和 我的Wep API 解决方案B XAML: 注意:在解决方案B中,我可以添加在解决方案A中不起作用的回退值,并可能在任务继续进行时添加一些其他UI更新。运行。您应该尝试使用一个好的框架来实现这一点,这已经影响到了该轮盘 看看: 这些扩展在IObservable上工作,IO

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

这两种解决方案之间是否有一种最佳做法,可以在WPF属性中显示结果而不阻塞UI?或者还有别的吗

注意:这两种解决方案都不是冻结用户界面,我已经查看了帖子和

我的Wep API 解决方案B XAML:


注意:在解决方案B中,我可以添加在解决方案A中不起作用的回退值,并可能在任务继续进行时添加一些其他UI更新。运行。

您应该尝试使用一个好的框架来实现这一点,这已经影响到了该轮盘

看看:

这些扩展在IObservable上工作,IObservable本身就是一个非常强大的工具:

Observable.FromAsync(async () =>
            {
                await Task.Delay(100);
                return 5;
            }).ToProperty(x => )

你应该试着用一个好的框架来实现这一点,它已经深深地感染了这个轮子

看看:

这些扩展在IObservable上工作,IObservable本身就是一个非常强大的工具:

Observable.FromAsync(async () =>
            {
                await Task.Delay(100);
                return 5;
            }).ToProperty(x => )

在这两种情况下,您都没有捕获到在尝试调用Web API时可能发生的任何错误。您可能希望将其记录到文件和/或向用户显示错误消息

在这种情况下,wait使它变得简单-您可以使用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 void。有时,这对于事件处理程序是必需的(至少在Windows窗体中-不确定WPF)


在这两种情况下,您都没有捕获到在尝试调用Web API时可能发生的任何错误。您可能希望将其记录到文件和/或向用户显示错误消息

在这种情况下,wait使它变得简单-您可以使用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 void。有时,这对于事件处理程序是必需的(至少在Windows窗体中-不确定WPF)


请注意,在绑定上设置
UpdateSourceTrigger=PropertyChanged
是毫无意义的。它仅在实际更新其源属性的绑定中有效,即双向或单向源绑定。在B中,从属性getter返回
GetAsyncProperty().Result
。谢谢!如果我想显示一个绑定到布尔值的微调器,以便知道更新何时完成,我可以在不使用
Task.Run(…).ContinueWith的情况下进行吗(x=>IsLoading=false…
?。结果是阻塞的,可能会导致WPF/UI环境中的死锁。不要使用.Result或.Wait!@PeterBons如果我在XAML中使用
IsAsync=True
,这不是问题。即使我使用了
IsAsync
,是否有可能在下一刻导致死锁?请注意设置
UpdateSourceRigger=Property在绑定上更改的
是毫无意义的。它只对实际更新其源属性的绑定有效,即双向或单向源绑定。在B中,返回
GetAsyncProperty()就足够了.Result
来自属性getter。谢谢!如果我想显示绑定到布尔值的微调器以了解更新何时完成,我可以在不使用
任务的情况下执行它。运行(…)。继续使用(x=>IsLoading=false…
?。结果是阻塞的,可能会导致WPF/UI环境中的死锁。不要使用.Result或.Wait!@PeterBons如果我在XAML中使用
IsAsync=True
,这不是问题。即使我使用了
IsAsync
,有没有可能会在下一刻导致死锁?谢谢!我不知道这个框架,我会考虑一下寻找我的个人用途。但我的公司和我并不信任互联网上的每个人,即使你说的是一个强大的框架…目前GitHub上只有3100个星星,我不知道5年后是否会有支持和更新。信任?它是开源的。它目前做得很好,那么你害怕什么?请不要试图重新发明轮子。这将花费你更多,而且可能会降低稳定性。然后关注可观察对象本身,它们是.NET的一部分。反应式编程非常简洁:)谢谢!我不知道这个框架,我会看看我的个人用途。但是我的公司和我不相信互联网上的每个人,即使你说的是一个强大的框架…目前GitHub上只有3100个星星,我不知道5年后是否会有支持和更新。相信吗?它是开源的。它在时刻很好,那么你害怕什么呢?请不要试图重新发明轮子。这会让你付出更多的代价,可能会降低稳定性。然后关注可观察对象本身,它们是.NET的一部分。反应式编程非常简洁:)
public string AsyncPropertyB
{
    get
    {
        return GetAsyncPropertyB();
    }
}

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

LoadTweetsCommand.ToProperty(this, x => x.TheTweets, out theTweets);
LoadTweetsCommand.ThrownExceptions.Subscribe(ex => /* handle exception here */);
Observable.FromAsync(async () =>
            {
                await Task.Delay(100);
                return 5;
            }).ToProperty(x => )
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);
}
public MyConstructor()
{
    SetAsyncPropertyA();
}

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