C# 从异步方法进行服务调用时线程被中止错误

C# 从异步方法进行服务调用时线程被中止错误,c#,.net,web-services,asynchronous,C#,.net,Web Services,Asynchronous,我有一个作为循环的一部分异步调用的方法,如下所示 List<Task> tasks = new List<Task>(); foreach (var cust in e.customers) { tasks.Add(Task.Run(() => exMan.perfomAction(cust, userId))); } await Task.WhenAll(tasks); 堆栈跟踪: at System.ServiceModel.Channels.Bin

我有一个作为循环的一部分异步调用的方法,如下所示

List<Task> tasks = new List<Task>();
foreach (var cust in e.customers)
{
  tasks.Add(Task.Run(() => exMan.perfomAction(cust, userId)));
}
await Task.WhenAll(tasks);
堆栈跟踪:

   at System.ServiceModel.Channels.Binding.EnsureInvariants(String contractName)
   at System.ServiceModel.Description.ServiceEndpoint.EnsureInvariants()
   at System.ServiceModel.Channels.ServiceChannelFactory.BuildChannelFactory(ServiceEndpoint serviceEndpoint, Boolean useActiveAutoClose)
   at System.ServiceModel.ChannelFactory.CreateFactory()
   at System.ServiceModel.ChannelFactory.OnOpening()
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.ChannelFactory.EnsureOpened()
   at System.ServiceModel.ChannelFactory`1.CreateChannel(EndpointAddress address, Uri via)
   at System.ServiceModel.ChannelFactory`1.CreateChannel()
   at System.ServiceModel.ClientBase`1.CreateChannel()
   at System.ServiceModel.ClientBase`1.CreateChannelInternal()
   at System.ServiceModel.ClientBase`1.get_Channel()
   at PriceListManagement.Domain.PricePriceListService.PriceListServiceClient.PriceListManagement.Domain.PricePriceListService.PriceListService.findEx(PriceListServiceFindExRequest request) in C:\Users\Richard\Documents\tfs\PriceListManagement\PriceListManagementAx2012\PriceListManagement.Domain\Service References\PricePriceListService\Reference.cs:line 1964

当所有项目都完成后,Task.wheall返回一个Task对象,我相信您会希望使用Task.WaitAll来代替等待所有任务完成的Task.WaitAll

从未正确检查/阻止的任务会导致各种奇妙的事情发生,当您通过Wheall返回任务时,很可能是这导致了问题。要么对返回的任务做些什么,要么切换到WaitAll——这是我期望看到的


因此,我做了两个改变,似乎已经有所不同,并且按照预期工作。服务调用已异步,正在等待

var axPriceList = await client.findExAsync(callContext, queryCriteria, documentContext);
现在正在等待调用包含以下代码的方法的根调用

private async Task CallingMethod(string cust, string userId)
{
  await MehodA(string cust, string userId);
}

private async Task MehodA(string cust, string userId)
{
    List<Task> tasks = new List<Task>();
    using (var throttler = new SemaphoreSlim(10))
    {
      foreach (var cust in e.customers)
      {
        tasks.Add(tasks.Add(Task.Run(async () =>
        {
          try
          {
            await exMan.perfomAction(cust, userId);
          }
          finally
          {
            throttler.Release();
          }
        }));
      }
    }
    await Task.WhenAll(tasks);
}

您应该提供异常的完整堆栈跟踪。是否有任何响应。在主线程中的任何任务内重定向?没有响应。在我的服务器代码中的任务内重定向。我不确定服务引用是否在做一些我不知道的事情。@RichardWatts什么叫你的代码?如果异步调用没有一直等待到调用的根,则通常会出现此错误。根代码在任务本身有机会完成之前终止,引发此错误。此外,WCF代理本身会生成基于任务的异步调用。使用Task.Run异步运行阻塞调用的结果是使用两个线程。是否有findExAsync方法?如果进行多个SOAP调用,可能应该检查ActionBlock和System.Threading.Channel。向同一服务拨打100个电话不会让服务的所有者很高兴。使用ActionBlock,您可以指定一定程度的并行性,例如3、5、10以限制并发执行。ActionBlock和通道都有输入缓冲区。为了防止在等待一次发送3个请求时缓存100个请求,可以设置一个绑定,以在块/通道已满时强制发布者等待。这是不对的。wait Task.WhenAll的行为与Task.WaitAll相同,但不阻塞当前线程。如果需要ask.WaitAll,则只意味着调用链上的某些内容没有正确等待异步操作,因此将wait Task.wheall更改为Task.WaitAll已修复该问题。在接受这个答案之前,我担心Panagiotis Kanavos暗示了链条上的某些东西没有正确等待。exMan.performAction是唯一被异步调用的方法,我想等待的就是这个方法?
private async Task CallingMethod(string cust, string userId)
{
  await MehodA(string cust, string userId);
}

private async Task MehodA(string cust, string userId)
{
    List<Task> tasks = new List<Task>();
    using (var throttler = new SemaphoreSlim(10))
    {
      foreach (var cust in e.customers)
      {
        tasks.Add(tasks.Add(Task.Run(async () =>
        {
          try
          {
            await exMan.perfomAction(cust, userId);
          }
          finally
          {
            throttler.Release();
          }
        }));
      }
    }
    await Task.WhenAll(tasks);
}