没有从异步ParallelLoopResult获得结果

时间:2015-11-30 21:34:08

标签: c# asynchronous async-await

当我尝试从异步任务中获取结果时,我得到了#34; System.Threading.Tasks.ParellelLoopResult"作为输出。我怎样才能得到正确的结果?

我希望能够调用Parallel.ForEach()进行并发查找,以检索传递给Customer方法的CustomerId值的getCustomerAsync()实例引用。一旦对Parallel.ForEach()的调用完成,我想返回一个Customer实例数组,其中该数组中的每个元素都对应于输入数组中的客户ID。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp2
{
public class Program
{
    public void Main(string[] args)
    {
        int[] id = { 1, 3, 4 };
        MethodCall mc = new MethodCall();
        var result = mc.getGustomerAsync(id).Result;

        Console.WriteLine(result);
        Console.ReadLine();
    }


}

public class Customer
{
    public int CustomerId { get; set; }
    public string CustomerName { get; set; }
    public string Address { get; set; }


}

public class CustomerList
{
    public List<Customer> customerList = new List<Customer>()
    {
        new Customer {CustomerId = 1, Address = "My Home1", CustomerName = "Piyush1" },
        new Customer {CustomerId = 2, Address = "My Home2", CustomerName = "Piyush2" },
        new Customer {CustomerId = 3, Address = "My Home3", CustomerName = "Piyush3" },
        new Customer {CustomerId = 4, Address = "My Home4", CustomerName = "Piyush4" },
        new Customer {CustomerId = 5, Address = "My Home5", CustomerName = "Piyush5" }

    };
}

public class MethodCall
{
    public Customer getGustomer(int customerId)
    {
        CustomerList list = new CustomerList();
        return list.customerList[customerId];
    }

    public async Task<System.Threading.Tasks.ParallelLoopResult> getGustomerAsync(int[] customerIds)
    {
        return await Task.Run(() => System.Threading.Tasks.Parallel.ForEach(customerIds, r =>
        {
            getGustomer(r);
        }));
    }
}

}

1 个答案:

答案 0 :(得分:0)

来自你的评论:

  

我想返回一个Customer []数组,其中每个元素对应于传递给getCustomerAsync()的ID的客户

好的,这更有意义。被削减,示例的其余部分可能是人为的,并不一定代表实际的现实场景。我暂时假设你真的想要一个async方法(即你不想在Parallel.ForEach()运行时阻塞调用线程),并且我们可以放心地忽略这个事实您每次调用CustomerList方法时都要重新验证getCustomer()(即实际上,您的代码将缓存只读列表或以其他方式有效地检索给定ID的客户信息)。

然后我觉得这样的事情对你的代码会更好:

public async Task<Customer[]> getGustomerAsync(int[] customerIds)
{
    Customer[] customers = new Customer[customerIds.Length];

    await Task.Run(() => System.Threading.Tasks.Parallel.ForEach(customerIds, r =>
    {
        customers[r] = getGustomer(r);
    }));

    return customers;
}

然后你可以这样打电话:

Customer[] customersResult = await mc.getCustomerAsync(customerIds);

或者,如果你绝对必须使用非异步方法(例如上面的代码示例中,您使用Main()方法调用的地方):

Customer[] customersResult = mc.getCustomerAsync(customerIds).Result;