无法在Parallel.Foreach内部使用await。错误:-'await'运算符只能在异步lambda表达式中使用 [英] Can not use await inside a Parallel.Foreach . error :- The 'await' operator can only be used within an async lambda expression

查看:411
本文介绍了无法在Parallel.Foreach内部使用await。错误:-'await'运算符只能在异步lambda表达式中使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在asp.net mvc-5 Web应用程序中具有以下方法:-

I have the following method inside my asp.net mvc-5 web application :-

public async Task <List<Details>> Get()
{
    Parallel.ForEach(resourcesinfo.operation.Details,new ParallelOptions { MaxDegreeOfParallelism = 20 }, (c) =>
    {
        ResourceAccountListInfo resourceAccountListInfo = new ResourceAccountListInfo();
        using (WebClient wc = new WebClient()) 
        {
            string url = currentURL + "resources/" + c.RESOURCEID + "/accounts?AUTHTOKEN=" + pmtoken;
            string tempurl = url.Trim();

            var json =  await wc.DownloadStringTaskAsync(tempurl);
            resourceAccountListInfo = JsonConvert.DeserializeObject<ResourceAccountListInfo>(json);
        }
        //code goes here

但是我收到此错误:-


'await'运算符只能在异步lambda表达式中使用。请考虑使用'async'修饰符标记该lambda表达式

The 'await' operator can only be used within an async lambda expression. Consider marking this lambda expression with the 'async' modifier

所以任何人都可以在thi上请

so can anyone adivce on this please ?

推荐答案

Parallel.ForEeach 不能用于异步函数,您需要使用更现代的类,例如 TPL Dataflow 。您可以通过将NuGet程序包安装到项目中来获取它 Microsoft.Tpl数据流 。您可以将先前的代码重新创建为

Parallel.ForEeach is not designed to work with asynchronous functions, you need to use more modern classes like the ones in TPL Dataflow. You get it by installing the NuGet package to your project Microsoft.Tpl.Dataflow. You could recreate your previous code as

private const int MAX_PARALLELISM = 20

public async Task <List<Details>> Get()
{
    var block = new ActionBlock<Entry>(async (c) => 
        {
            ResourceAccountListInfo resourceAccountListInfo = new ResourceAccountListInfo();
            using (WebClient wc = new WebClient()) 
            {
                string url = currentURL + "resources/" + c.RESOURCEID + "/accounts?AUTHTOKEN=" + pmtoken;
                string tempurl = url.Trim();

                var json =  await wc.DownloadStringTaskAsync(tempurl);
                resourceAccountListInfo = JsonConvert.DeserializeObject<ResourceAccountListInfo>(json);
            }
            //code goes here
        }
        ,new ExecutionDataflowBlockOptions 
                   { 
                         MaxDegreeOfParallelism = MAX_PARALLELISM
                   });

    foreach(var entry in resourcesinfo.operation.Details)
    {
        await block.SendAsync(entry);
    }

    block.Complete();
    await block.Completion;

    //More code here    
}






经过一番思考,这是一个稍微复杂一点的版本,它执行从读取记录到从 Get()

private const int MAX_PARALLELISM = 20

public async Task<List<Details>> Get()
{
    List<Details> result = new List<Details>();

    var getRecordBlock = new TransformBlock<Entry, ResourceAccountListInfo>(async (c) =>
        {
            ResourceAccountListInfo resourceAccountListInfo = new ResourceAccountListInfo();
            using (WebClient wc = new WebClient())
            {
                string url = currentURL + "resources/" + c.RESOURCEID + "/accounts?AUTHTOKEN=" + pmtoken;
                string tempurl = url.Trim();

                var json = await wc.DownloadStringTaskAsync(tempurl);
                resourceAccountListInfo = JsonConvert.DeserializeObject<ResourceAccountListInfo>(json);
            }
            return resourceAccountListInfo;
        }
        , new ExecutionDataflowBlockOptions
        {
            MaxDegreeOfParallelism = MAX_PARALLELISM
        });

    //Defaults to MaxDegreeOfParallelism = 1
    var addToListBlock = new ActionBlock<ResourceAccountListInfo>(info =>
    {
        Details detail = TurnResourceAccountListInfoInToDetails(info);
        result.Add(detail);
    });

    getRecordBlock.LinkTo(addToListBlock, new DataflowLinkOptions { PropagateCompletion = true});

    foreach (var entry in resourcesinfo.operation.Details)
    {
        await getRecordBlock.SendAsync(entry);
    }

    getRecordBlock.Complete();
    await addToListBlock.Completion;

    return result;
}

这篇关于无法在Parallel.Foreach内部使用await。错误:-'await'运算符只能在异步lambda表达式中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆