【发布时间】:2018-10-28 18:19:37
【问题描述】:
我正在使用 MVVM 开发 Xamarin.Forms 应用程序。在我的视图模型中,我想从 API 中获取所有患者。这是代码:
public async Task GetAllPatients()
{
try
{
isFetchingData = true;
var response = await httpClient.GetStringAsync(baseUrl + "/patient?query=ma");
var resultPatients =
JsonConvert.DeserializeObject<ObservableRangeCollection<PatientViewModel>>
(testJson,jsonSerializerSettings);
AllPatients.ReplaceRange(resultPatients);
Patients.ReplaceRange(resultPatients);
}
catch(Exception e)
{
Console.WriteLine("*****ERROR kon API niet ophalen");
Console.WriteLine(e.Message);
}
finally
{
CheckIfEmptyList();
isFetchingData = false;
}
}
起初我只是从我的代码中的一个 json 字符串 (testJson) 硬编码 API,一切都很顺利。但是从我将 htppClient 排除在评论之外的那一刻起,发生了一些奇怪的事情(即使我没有使用代码中的变量(尽管我使用变量时得到了相同的结果))。
finally块没有被执行。
也就是说,当我去调试应用程序时,代码会经过finally并检查列表是否为空并将isFetchingData设置为false。但我没有在屏幕上看到这种情况。如果列表为空,则应该出现一个标签,但现在当列表不为空时该标签不会消失。 INotifyPropertyChanged 运行良好,因为没有 httpClient 它运行顺利。
我对异步编程很陌生,所以也许我忘了实现一些必须确保 GetStringAsync 正确结束的东西?也许它一直在获取数据,这就是为什么我从来没有看到 finally 块执行(即使它在屏幕后面执行)。我已经阅读了一些关于异步编程的文章,但找不到可以帮助我的东西。
我还必须说,这个方法是从构造函数中调用的,这使得异步运行有点困难。我尝试在没有 async await 的情况下调用它,我尝试这样调用它:
Task.Run(async ()=> { await GetAllPatients(); });
我尝试了使用和不使用ConfigureAwait(false),但这也没有什么不同。
【问题讨论】:
-
Task.Run 不会在 UI 线程上运行。我认为你得到了一个例外但没有抓住它。
-
@Crowcoder 我想我对这个概念太陌生了,无法理解你的意思。你能更准确地说出你的意思吗?或许举个例子说明我可以做些什么来解决这个问题?
-
Task.Run 将在线程池线程上执行代码,但您只能从主 UI 线程进行 UI 更新。谷歌人喜欢 Cleary、Toub、Skeet。你应该重构,这样你就不需要Task.Run了,除了线程问题,它不适合I/O操作。
标签: c# xamarin.forms async-await try-catch-finally