异步任务没有返回主线程

时间:2017-07-12 17:28:54

标签: c# asp.net-mvc async-await

我认为这与我非常糟糕的异步编程有关。

在这里。我使用异步方法获取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(subscriber)语句之后。

这是从

调用的
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;
}

3 个答案:

答案 0 :(得分:8)

这里有很多错误:

删除所有不良部分会给我们留下:

Task.Run

答案 1 :(得分:1)

不要在具有同步上下文的环境中使用.Result - 它会创建循环等待。

一般来说,如果可能的话,尽量使用async“一直向下” - 即如果你要使用async / await,你应该使用async / await

有关详细信息,请参阅Stephen Cleary的Don't Block on Async Code

答案 2 :(得分:-1)

问题的第一部分是,由于一些奇怪的原因,你将任务包装在另一个任务中。将您的方法更改为:

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;
}