加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 多种异步方法,最好使用WhenAll具有不同的返回类型

发布时间:2020-12-15 23:23:07 所属栏目:百科 来源:网络整理
导读:我有一个异步控制器动作方法,它在我的后端调用4个异步方法,从每个方法返回List.每个方法的对象列表都不同.即列表清单等 我有这样的工作: BizProvider bp = new BizProvider();Listbiz.Customer custReturn = await bp.GetCustomerAsync();Listbiz.Account a
我有一个异步控制器动作方法,它在我的后端调用4个异步方法,从每个方法返回List.每个方法的对象列表都不同.即列表清单等

我有这样的工作:

BizProvider bp = new BizProvider();
List<biz.Customer> custReturn = await bp.GetCustomerAsync();
List<biz.Account> acctReturn = await bp.GetAccountAsync();
...plus 2 more
List<object> returnArr = new List<object>();
returnArr.Add(custReturn);
returnArr.Add(acctReturn);  ...plus 2 more
return JsonConvert.SerializeObject(returnArr);

我应该因为多个任务而使用Task.WhenAll吗?

微软的例子
https://msdn.microsoft.com/en-us/library/hh194874%28v=vs.110%29.aspx

所有任务都返回List< int>

所以我使用了抽象类,并且我的所有列表对象类型都继承自此.
并且我更改了业务对象提供程序的返回类型以返回抽象类型的List
所以现在我能做到:

var tasks1 = new List<Task<List<Biz.AbstractClass>>>();
tasks1.Add(bp.GetCustomerAsAbstractAsync());
tasks1.Add(bp.GetAccountAsAbstractAsync());
...plus 2 more

然后我打电话
????var continuation = Task.WhenAll(tasks1);

然后执行它到达.Results的下一行然后停止执行???

foreach (var result in continuation.Result)
                                       ^ stops here

我打电话

returnArrays.Add(result1);
return JsonConvert.SerializeObject(returnArrays);

但这些永远不会受到打击……我不知道为什么.
也许我不需要一个WhenAll,但后来我仍然好奇出了什么问题.
也许我需要等待特定的函数,或以某种方式调用Action,就像在Microsoft链接中函数被内联调用一样.

Task.Run(async () => { x=x,etc...)

编辑20150306 =>添加更多实施细节

CustMan cm = new CustMan(); 
List<object> returnArr = new List<object>();
var aTask = cm.GetCustomersAsync(); 
var bTask = cm.GetAccountsAsync(); 
await Task.WhenAll(aTask,bTask);  
returnArr.Add(aTask.Result);//same for bTask <-- breakpoint never hits 
return JsonConvert.SerializeObject(returnArr); 
//also .js ajax return method never comes back.

//in CustMan()
public async Task<List<biz.Customer>> GetCustomersAsync() {
    List<biz.Customer> custList = await (from contact in ObjectContextDb.GetData<da.ContactInfo>()//<--generic returns IQueryable
     join customerContact in ObjectContextDb.GetData<da.CustomerContact>() on contact.Id equals customerContact.ContactInfoID
     join customerOrg in ObjectContextDb.GetData<da.CustomerOrganisation>() on customerContact.OrgID equals customerOrg.Id
     orderby contact.LastName
     select new biz.Customer {
       CustomerContactInfo = new biz.Contact() {
         ID = contact.Id,WorkPhone = contact.WorkPhone
       },CustomerOrg = new biz.CustomerOrganisation {
         ID = facultyOrg.Id,Name = facultyOrg.OrgName,ClientID = (customerContact.ClientID.HasValue ? customerContact.ClientID.Value : 0)
       }
     }).ToListAsync<biz.Customer>();
    return custList;// <-- Breakpoint hits here,the List has items
}

public async Task<List<biz.Account>> GetAccountsAsync()
{
 var roles = (from acctType in ObjectContextDb.GetData<da.AccountInType>()
  join r in ObjectContextDb.GetData<da.AccountType>() on acctType.AccountTypeID equals r.ID
  select new
  {
   AccountId = acctType.AccountID,Type = r.TypeName
  });   //.ToList();

  List<biz.Account> allContacts = await (from account in ObjectContextDb.GetData<da.Account>()
       orderby account.Name
       select new biz.Account()
       {
         Number = account.Id,Name = account.Name,Roles = (from r in roles where account.Id == r.AccountId select r.Type).ToList()
       }).ToListAsync<biz.Account>();

  return allContacts;//  <-- Breakpoint hits here,the List has items
}

在没有WhenAll的情况下调用Manager类方法的方法!

CustMan cm = new CustMan(); 
List<object> returnArrays = new List<object>();
List<biz.Customer> custReturn = await cm.GetCustomersAsync();
List<biz.Account> acctReturn = await cm.GetAccountsAsync();

returnArrays.Add(custReturn);
returnArrays.Add(acctReturn);

return JsonConvert.SerializeObject(returnArrays);

解决方法

您可以使用Task.WhenAll而无需更改任何内容.只需将任务存储在变量中,然后添加其结果:

var aTask = GetAAsync();
var bTask = GetBAsync();
...
await Task.WhenAll(aTask,bTask);
returnArr.Add(aTask.Result);
returnArr.Add(bTask.Result);

但是,在您的情况下,异步操作使用实体框架doesn’t support multiple operations concurrently,因此您不能这样做.

一次呼叫并等待您的操作:

returnArr.Add(await GetAAsync());
returnArr.Add(await GetBAsync());  
...

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读