Ошибка при прерывании потока при вызове службы из асинхронного метода - PullRequest
0 голосов
/ 17 декабря 2018

У меня есть метод, который вызывается асинхронно как часть цикла, как показано ниже

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

Этот метод вызывает несколько других методов.Один из этих методов делает сервисный вызов.

Я получаю сообщение об ошибке ..

Тема была прервана.

Приложение не всегда выдает ошибку в одной и той же строке кода.Это может быть когда инициализируется ссылка на сервис, когда устанавливается одно из его свойств или когда я выполняю вызов.Трассировка стека отличается в зависимости от того, какая строка кода вызывает исключение

Когда я вызываю этот метод синхронно, он работает нормально, вызывает службу и получает ответ.Когда я вызываю службу асинхронно, я получаю сообщение об ошибке

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 голосов
/ 19 декабря 2018

Итак, я сделал два изменения, которые, кажется, изменили ситуацию и работают как положено.Вызов службы выполнен асинхронно и ожидается.

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);
}
0 голосов
/ 17 декабря 2018

Task.WhenAll возвращает объект задачи, когда все элементы выполнены, я полагаю, вы захотите использовать Task.WaitAll вместо этого, который ожидает завершения всех задач.

Задачи, которые никогда не проверяются / блокируются должным образом, вызываютвсякие замечательные вещи случаются, и когда вы возвращаете задачу через WhenAll, вероятно, именно это и вызывает проблему.Либо сделайте что-нибудь с возвращенной Задачей, либо переключитесь на WaitAll - что я и ожидал бы увидеть

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

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

...