Ami*_*ich 5 .net c# asynchronous task-parallel-library async-await
我有一个使用async task
Now 执行长动作的方法,我想添加一个在同一方法中透明的缓存机制.现在,我总是可以获取我的缓存结果并用一个Task包装它以便它"工作"但我想阻止我将获得的上下文切换.
这是我的一个例子:
var result = await LongTask();
private async Task<string> LongTask()
{
return await DoSomethingLong();
}
Run Code Online (Sandbox Code Playgroud)
这是我想要的一个例子:
var result = await LongTask();
private async Task<string> LongTask()
{
if(isInCache)
{
return cachedValue(); // cache value is a const string you can do return "1" instead.
}
// else do the long thing and return my Task<string>
return await DoSomethingLong();
}
Run Code Online (Sandbox Code Playgroud)
现在我很惊讶地看到这个编译和工作
Something告诉我,我没有正确地做到这一点.
这是我测试的另一个类似的例子:
private async Task<string> DownloadString(bool sync)
{
using (WebClient wc = new WebClient())
{
var task = wc.DownloadStringTaskAsync("http://www.nba.com");
if(sync)
return task.Result;
return await task;
}
}
Run Code Online (Sandbox Code Playgroud)
这是代码:
var res = DownloadString(true);
string str1 = await res;
var res2 = DownloadString(false);
string str2 = await res2;
Run Code Online (Sandbox Code Playgroud)
从我在这里 阅读task.Result的内容同步执行任务并返回一个string.现在我通过Fiddler看到了请求,return task.Result即使我看到一个200 OK和我等了很长时间,我的程序仍然停留在线上.
底线:
context switch overhead?DownloadString被卡住了?首先,如果在调用async方法后返回的任务已经完成,则不会有上下文切换,因为不需要任何上下文切换.所以这是完全可以接受的:
private async Task<string> LongTask()
{
if(isInCache)
{
return cachedValue(); // cache value is a const string you can do return "1" instead.
}
// else do the long thing and return my Task<string>
return await DoSomethingLong();
}
Run Code Online (Sandbox Code Playgroud)
但是,在缓存结果的情况下,async机制是多余的.这种开销是微不足道的大部分,但你可以通过删除既提高性能async和await并使用一张已完成的任务Task.FromResult:
private Task<string> LongTask()
{
if(isInCache)
{
return Task.FromResult(cachedValue());
}
// else do the long thing and return my Task<string>
return DoSomethingLong();
}
Run Code Online (Sandbox Code Playgroud)
...当您编写"await someObject;"时,编译器将生成检查someObject表示的操作是否已完成的代码.如果有,则执行在等待点上同步继续.如果没有,生成的代码将连续委托连接到等待的对象,这样当表示的操作完成时,将调用该连续委托
Task.Result不同步执行任务,它同步等待.这意味着调用线程被阻塞,等待任务完成.当您在具有SynchronizationContext可能导致死锁的环境中使用它时,因为线程被阻止并且无法处理任务的完成.您不应该Result在尚未完成的任务上使用该属性.
| 归档时间: |
|
| 查看次数: |
1338 次 |
| 最近记录: |