api - 在后台线程上运行数据下载
问题描述
我正在构建一个新应用程序,因为我希望它像每个人一样流畅,所以我想使用一个后台线程来负责使用 restsharp 下载所有数据。我也遵循 MVVM 模式。我已经阅读了很多关于 task.run 以及如何正确使用它以及整个 async-await 主题的内容。但由于我对这一切都是陌生的,我不确定我应该如何正确地做事。我有很多代码,所以我会简短地尝试解释我在做什么,然后放一个片段。
所以我开始创建一个服务类,其中包含所有使用 restsharp 获取数据的函数。在我的 ViewModel 中,我一开始就调用了这些函数。我尝试使用任务并在后台线程上运行这些功能,但应用程序在初始屏幕上被阻止。显然那是因为我做错了......所以我决定问你们。
例如,我有这个功能:
public string GetResPor()
{
var restClient = new RestClient { BaseUrl = new Uri("http://xxx.xxx.xxx.xxx:xxxx") };
var request = new RestRequest
{
Resource = "getCliPor",
Method = Method.GET
};
request.AddParameter(new Parameter { Name = "idt", Value = GetImAsync().GetAwaiter().GetResult(), Type = ParameterType.GetOrPost });
var result = restClient.Execute(request);
Port = result.Content;
return Port;
}
当我在 Task 上转换它时:
public async Task<string> GetResPor()
{
var restClient = new RestClient { BaseUrl = new Uri("http://xxx.xxx.xxx.xxx:xxxx") };
var request = new RestRequest
{
Resource = "getCliPor",
Method = Method.GET
};
request.AddParameter(new Parameter { Name = "idt", Value = GetImAsync().GetAwaiter().GetResult(), Type = ParameterType.GetOrPost });
var result = await restClient.ExecuteTaskAsync(request);
Port = result.Content;
return Port;
}
在 ViewModel 上,我首先创建我的服务类的新实例,然后:
Port = RD.GetRestauPort().GetAwaiter().GetResult();
这就是应用程序被阻止的地方,没有例外。
解决方案
为了简单起见,让我们从基础开始。为了在后台线程中运行某些东西,最简单的方法是在Task.Run()
. 这是做什么的:
将指定的工作排入队列以在 ThreadPool 上运行并返回该工作的任务或
Task<TResult>
句柄。
基本上,您将工作委托给 TreadPool,它会为您处理所有事情 - 寻找工作人员,等待工作人员完成其工作(在新线程上),然后通知您结果。
所以,基本上,无论你想在后台线程中做什么,简单的解决方案都是将它包装在 a 中Task.Run()
并等待它的结果,以防你需要它。
另外,避免使用GetAwaiter().GetResult()
. 异步编程中的简单规则是 - 如果可以等待,则一直等待。
您可以阅读有关主题的更多信息
推荐阅读
- amazon-web-services - 尝试在一个 terraform 文件中创建 2 个 ASG
- reactjs - 用钩子在组件内部创建组件的惯用方法是什么?
- python - 如何从网站获取统计数据并将其转换为 python 上的 DataFrame?
- php - 使用 Api 资源在嵌套的 BelongsToMany 中急切加载 Pivot
- python - 结合两个 python 脚本进行网络搜索
- php - PHP 为什么我不能将我的函数命名为“包含”?
- api - 条纹 SCA 合规性
- android - 我必须做些什么才能从头开始用新的应用程序更新我当前的应用程序?
- php - 将 Twig 独立项目部署到 Live Server
- arrays - 连续无序数组中的不规则性