【发布时间】:2015-10-07 14:09:34
【问题描述】:
我有 WP 8.1 应用程序,它经常使用 Web 服务,我希望它尽可能地响应。来自 iOS 开发经验 - 有一条严格的规则:“不要在 UI 线程中进行任何复杂的计算!不管你如何达到这个目的:使用块或使用 GCD”。
并非所有 API 都有异步版本的问题,例如应用程序中的 JSON.NET、SQLite 或任何自己的复杂算法。我读过很多 articles 将 Task.Run 和 Task.Factory.StartNew 定义为不好的做法 + this。
那么,这样写代码好吗?它会导致一些 cpu 过载/电池耗尽/稳定性问题吗?如果异步包装器是个坏主意 - 使复杂操作异步(后台线程)的正确方法是什么?
protected async Task<T> GetDataAsync<T>(string uriString, CancellationToken cancellationToken = default(CancellationToken))
{
var uriToLoad = new Uri(uriString);
using (var httpClient = new HttpClient())
{
var response= await httpClient.GetAsync(uriToLoad, cancellationToken).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
cancellationToken.ThrowIfCancellationRequested();
var dataString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested();
// async wrapped call to sync API
var result = await Task.Factory.StartNew(() => JsonConvert.DeserializeObject<T>(dataString), cancellationToken).ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested();
return result;
}
}
【问题讨论】:
-
Task.Run/Task.Factory.StartNew适用于 CPU 密集型操作。对于没有“真正”异步 API 实现的 IO 绑定的,这是在后台执行某些操作的唯一方法,因为替代方法是在 UI 线程中执行相同操作。不要太明确。
标签: c# .net windows-runtime windows-phone async-await