C# WPF异步属性的最佳实践
假设我有一个长时间运行的Web API调用(异步方法),它返回一个字符串 这两种解决方案之间是否有一种最佳做法,可以在WPF属性中显示结果而不阻塞UI?或者还有别的吗 注意:这两种解决方案都不是冻结用户界面,我已经查看了帖子和 我的Wep API 解决方案B XAML: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
注意:在解决方案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
}
}