[英]Async Task not returning to main thread
我認為這與我真正糟糕的異步編程有關。
來了 我正在使用異步方法來獲取mailchimp訂戶,但結果只是掛起,並且從未返回主線程。
異步方法
public async Task<List<Subscriber>> GetMailChimpSubscribers()
{
TaskCompletionSource<List<Subscriber>> result = new TaskCompletionSource<List<Subscriber>>();
await Task.Run(async () =>
{
var subscribers = new List<Subscriber>();
var listId = "";
var members = await _manager.Members.GetAllAsync(listId);
foreach (var item in members)
{
var sub = new Subscriber();
sub.Email = item.EmailAddress;
subscribers.Add(sub);
}
result.SetResult(subscribers);
});
return result.Task.Result;
}
這完全掛在result.SetResult(subscribers)語句之后。
這是從
public static List<Subscriber> GetSubscribers()
{
MailchimpHelper helper = new MailchimpHelper();
var subscribers= helper.GetMailChimpSubscribers();
return subscribers.Result;
}
這到底是怎么了? 設置錯誤嗎?
PS:mailchimp或api沒有問題,在控制台中效果很好。 這純粹是異步編程的問題
更新:
如果有人遇到這種情況。 博客幫助清除了很多
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
下面的答案和博客的工作解決方案。
public async Task<List<Subscriber>> GetMailChimpSubscribers()
{
var subscribers = new List<Subscriber>();
var listId = "";
var members =
await _manager.Members.GetAllAsync(listId).**ConfigureAwait(false)**;
foreach (var item in members)
{
var sub = new Subscriber();
sub.Email = item.EmailAddress;
subscribers.Add(sub);
}
return subscribers;
}
public static List<Subscriber> GetSubscribers()
{
MailchimpHelper helper = new MailchimpHelper();
var subscribers= helper.GetMailChimpSubscribers();
subscribers.Wait();
return subscribers.Result;
}
這里有很多錯誤:
TaskCompletionSource<T>
令人困惑和不必要的使用。 Task.Run
是不必要的。 除去所有不良零件,我們將獲得:
public async Task<List<Subscriber>> GetMailChimpSubscribersAsync()
{
var subscribers = new List<Subscriber>();
var listId = "";
var members = await _manager.Members.GetAllAsync(listId);
foreach (var item in members)
{
var sub = new Subscriber();
sub.Email = item.EmailAddress;
subscribers.Add(sub);
}
return subscribers;
}
public static async Task<List<Subscriber>> GetSubscribersAsync()
{
MailchimpHelper helper = new MailchimpHelper();
return await helper.GetMailChimpSubscribersAsync();
}
在具有同步上下文的環境中不要使用.Result
它會創建循環等待。
通常,如果可能,嘗試“一路向下”使用async
即,如果要完全使用async
/ await
,則應僅使用async
/ await
。
有關更多詳細信息,請參見Stephen Cleary的“不要阻止異步代碼” 。
問題的第一部分是,出於某種奇怪的原因,您正在將任務包裝在另一個任務中。 將您的方法更改為此:
public async Task<List<Subscriber>> GetMailChimpSubscribers()
{
var subscribers = new List<Subscriber>();
var listId = "";
var members = await _manager.Members.GetAllAsync(listId);
foreach (var item in members) //this foreach could be a simpler LinQ statement
{
var sub = new Subscriber();
sub.Email = item.EmailAddress;
subscribers.Add(sub);
}
return subscribers;
}
您還應該使用await來調用此方法,但是如果不可能,則將方法更改為此:
public static List<Subscriber> GetSubscribers()
{
MailchimpHelper helper = new MailchimpHelper();
var subscribers = helper.GetMailChimpSubscribers();
subscribers.Wait();
return subscribers.Result;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.