我们有一个工作实现,执行I/O操作,从Azure Blob存储以异步/等待方式从Blob返回数据。
//Method1 is not async, this is what is called from the controller
public IEnumerable<Data> Method1()
{
//Running the async method and returning the result from task
return Task.Run(() => GetDataAsync()).Result;
}
private async Task<IEnumerable<Data>> GetDataAsync()
{
//There are multiple blob address where the data is held. The code creates, in parallel multiple tasks for each address.
//It returns tasks that will be run in Async pattern
var tasks = multipleBlobAddress.AsParallel.Select(blobAddress =>{
Task<IEnumerable<Data>> task = GetDataFromBlobsAsync(blobAddress);
return task;
});
//Awaits all tasks to complete
var completedTasks = await Task.WhenAll<IEnumerable<Data>>(tasks);
//Selects all the tasks and returns them. Each tasks has data.
return completedTasks.SelectMany(t => t);
}
private Task<IEnumerable<Data>> GetDataFromBlobsAsync(string address)
{
//Opens the blob and reads from it
using (var blobStream = blobService.OpenRead(address))
{
//Deserialises the data read from the blob
data = service.DeserialiseData(blobStream);
}
return Task.FromResult<IEnumerable<Data>>(data);
}我们已经了解到,从blobs读取数据的最佳方法是遵循异步/等待模式,而不是使用AsParallel方法(其他建议最受欢迎)。我有以下问题:
如果您需要有关代码的任何额外信息,我将很高兴地提供它,并希望使它更清楚。
发布于 2016-11-01 14:58:11
从来没有必要这样做:
return Task.Run(() => GetDataAsync()).Result;为什么要启动一个新任务,然后与.Result同步等待?当您发现同步上下文可能导致死锁时,这是一种代码,稍后会咬您一口。请参阅关于异步死锁主题的斯蒂芬·克利里的博客文章。斯蒂芬的博客绝对是aysnc和await信息的宝库。
要么使用同步api (从控制器一直到Azure ),要么使用异步api(使用async和await)。不要混为一谈--这是错误的来源,也是毫无意义的。当线程可能做其他事情时,Aysnc是有用的。例如,在一个为请求提供服务的web应用程序中。如果web应用程序被.Result或Wait阻塞,那么就没有好处,您应该使用同步API。
发布于 2016-11-01 13:54:16
先回答问题,
两者的不同之处在于并行/线程执行的代码相同,但参数不同。
异步等待是一种让计算机决定停止工作当前进程的机制,等待,因为响应当时还没有准备好。电脑可以去做别的事情。返回异步结果后,计算机将返回并继续运行。基本上不要阻塞主线程。
好的,看看您的代码,删除method1并使用异步,然后等待所有的代码。
我试图更改您的代码,但由于代码不完整,我只能尝试为您填补空白。
public async Task<IEnumerable<Data>> GetDataAsync()
{
//There are multiple blob address where the data is held. The code creates, in parallel multiple tasks for each address.
//It returns tasks that will be run in Async pattern
var tasks = multipleBlobAddress.AsParallel.Select(async blobAddress =>
{
IEnumerable<Data> task = await GetDataFromBlobsAsync(blobAddress);
return task;
});
//Awaits all tasks to complete
var completedTasks = await Task.WhenAll((IEnumerable<Data>)(tasks));
//Selects all the tasks and returns them. Each tasks has data.
return completedTasks.SelectMany(t => t);
}
private async Task<Data> GetDataFromBlobsAsync(string address)
{
//Opens the blob and reads from it
using (var blobStream = await blobService.OpenRead(address)) // at the bottom there should be a Async method
{
//Deserialises the data read from the blob
data = service.DeserialiseData(blobStream);
}
return data;
}https://codereview.stackexchange.com/questions/145611
复制相似问题