我已经读过在网络上使用async / await是有益的,所以我想将它应用于将文件上传到azure blob。
当我在方法上使用.Wait()
时,应用程序会在await _Container.CreateIfNotExistsAsync();
上停止。我想使用.Wait()
,因为InitializeCategories(context)
方法需要等待blob上传才能循环播放。
我对使用多线程完全陌生,有人可以解释为什么会发生这种情况并告诉我如何修复它吗?
protected override void Seed(ApplicationDbContext context)
{
base.Seed(context);
InitializeImages().Wait();
InitializeCategories(context);
}
public static async Task InitializeImages()
{
_PlaceHolderImage = "placeholder-categories.jpg";
_StorageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
_BlobClient = _StorageAccount.CreateCloudBlobClient();
_Container = _BlobClient.GetContainerReference("images");
await _Container.CreateIfNotExistsAsync();
//To view the blob in the browser
await _Container.SetPermissionsAsync(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Blob });
CloudBlockBlob blockBlob = _Container.GetBlockBlobReference(_PlaceHolderImage);
await blockBlob.UploadFromFileAsync(HttpContext.Current.Server.MapPath("~/Content/Images/" + _PlaceHolderImage), FileMode.Open);
}
public static void InitializeCategories(ApplicationDbContext db)
{
// Loop over items within the container and output the length and URI.
foreach (IListBlobItem item in _Container.ListBlobs())
{
if (item.GetType() == typeof(CloudBlockBlob))
{
CloudBlockBlob blob = (CloudBlockBlob)item;
Console.WriteLine("Block blob of length {0}: {1}", blob.Properties.Length, blob.Uri);
}
}
}
答案 0 :(得分:3)
我已经读过在网络上使用async / await是有益的
是的,但是为什么?
答案是:async
是有益的(特别是对于基于I / O的代码),这样你就可以释放线程做其他事情。在ASP.NET应用程序中,这意味着您有更多线程可用于处理传入请求。哦,等等......
protected override void Seed(ApplicationDbContext context)
当你的应用程序正在处理它的第一个请求(以及播种数据库)时,没有任何一点可以释放线程,因为他们无法做任何事情,直到数据库被播种为止。
所以在这种情况下,你应该只是同步上传。
有人可以解释为什么会这样吗
我有一个更详细的blog post,但总结一下:
await
会捕获"上下文",并将在该上下文中继续执行async
方法。HttpContext.Current
,当前页面文化等内容。因此,当您在请求上下文(Wait
)中阻塞某个线程时,async
方法无法完成,因为它正在等待该请求上下文空闲。当然,Wait
正在等待async
方法完成,因此您最终会遇到死锁。