gpt4 book ai didi

c# - 覆盖时异步无效

转载 作者:行者123 更新时间:2023-11-30 14:23:26 24 4
gpt4 key购买 nike

我知道 async void 方法的弊端,但我不完全确定在覆盖方法时解决问题的最佳方法。

比如说,我有以下代码:

protected override async void PageRefreshed()
{
BoundDataField = await LoadDataFromWeb();
}

我知道这是一件非常糟糕的事情,但最好的解决方案是什么?

  1. LoadDataFromWeb().ContinueWith(r => BoundDateField = r.Result);
  2. Task.Run(async ()=> await LoadDataFromWeb())).Wait;
  3. LoadDataFromWeb().Wait
  4. BoundDataField = LoadDataFromWeb.Result

我很确定 3 和 4 确实不行,因为它们会阻塞 UI 线程。我错过了另一种解决方案吗?

最佳答案

I'm pretty sure that 3 & 4 are real no nos as they will be blocking the UI thread.

不只是阻塞,还有quite possibly deadlocking ,也是。

Is there another solution I have missed?

您要做的是异步检索数据绑定(bind)属性的值。我在我的 MSDN article on asynchronous data binding 中详细介绍了这一点.

首先,要认识到的核心是,正如所写的那样,这是不可能的。有两个相互矛盾的要求:

  • 计算机必须立即显示一些内容。
  • 您需要获取要显示的数据,这需要时间。

所以,你需要妥协:

  • 计算机获取一些占位符数据或微调器或其他内容以立即显示。
  • 您在真实数据到达时更新显示。

这样说,代码就更直接了:

protected override async void PageRefreshed()
{
BoundDataField = "placeholder"; // synchronous immediate placeholder data
BoundDataField = await LoadDataFromWeb(); // asynchronous update
}

或:

protected override async void PageRefreshed()
{
// Synchronously show spinner
IsBusy = true;

// Asynchronously load data and then hide spinner
BoundDataField = await LoadDataFromWeb();
IsBusy = false;
}

请注意,这个简单的解决方案不能很好地处理错误,也不能处理可能无序更新该字段的多个“刷新”。更高级的方法是使用类似 my NotifyTask<T> type 的方法。来自 Nito.Mvvm.Async NuGet 包:

protected override void PageRefreshed()
{
BoundDataField = NotifyTask<TData>.Create(LoadDataFromWeb());
}

此方法还需要更新您的数据绑定(bind)代码; BoundDataField.Result现在是实际数据值,BoundDataField.IsNotCompleted , BoundDataField.IsFaulted ,以及其他属性可用于让您的数据绑定(bind)响应进行中或故障状态。

关于c# - 覆盖时异步无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45352779/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com