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

时间:2018-12-17 16:12:40

标签: 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);

此方法调用服务器其他方法。这些方法之一进行服务调用。

我收到错误消息。

  

线程被中止。

应用程序并非总是在同一行代码上出错。可能是在初始化服务引用,设置其属性之一或在Im进行调用时。堆栈跟踪因代码行引发异常而有所不同

当我同步调用此方法时,它可以正常工作,调用服务并获得响应。当我异步调用服务时,出现错误

到目前为止,Google尚无法为我提供任何帮助

根据要求,这是应用程序调用服务时发生错误时的堆栈跟踪(此变化取决于代码行引发异常)

代码行错误:

var axPriceList = client.findEx(callContext, queryCriteria, documentContext);

Stacktrace:

   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

2 个答案:

答案 0 :(得分:0)

因此,我进行了两项更改,这些更改似乎有所不同,并且按预期运行。服务调用已异步进行,正在等待。

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

答案 1 :(得分:-2)

Task.WhenAll在所有项目都完成后返回一个任务对象,我相信您会想使用Task.WaitAll来等待所有任务完成。

从未正确检查/阻止的任务会导致发生各种奇妙的事情,并且当您通过WhenAll返回任务时,很可能是导致问题的原因。用返回的Task做些事情,或切换到WaitAll-这是我期望看到的

GITHUB-1985

https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.whenall?view=netframework-4.7.2