问题
I have a method that is called asynchonously as part of a loop as below
List<Task> tasks = new List<Task>();
foreach (var cust in e.customers)
{
tasks.Add(Task.Run(() => exMan.perfomAction(cust, userId)));
}
await Task.WhenAll(tasks);
This method calls serveral other methods. One of these methods makes a service call.
I get the error..
Thread was being aborted.
The application doesn't always error on the same line of code. It might be when the service reference is being initialized, when one of it's properties is being set, or when Im making the call. The stack trace is different dependent on what line of code throws the exception
When I call this method synchonously it works fine, calls the service and gets a response. When I call the service Asynchonously I get the error
Google has not been able to help me so far, any ideas
As requested here's the stacktrace when the app errors from calling the service (this changes dependent on what line of code throws the exception)
Line of code erroring:
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
回答1:
So I've made two changes that seems to of made a difference and is working as expected. The service call has been made async and is awaited.
var axPriceList = await client.findExAsync(callContext, queryCriteria, documentContext);
The root call which calls the method containing the code below is now awaited
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);
}
回答2:
Task.WhenAll returns a task object when all items have completed, I believe you'll want to use Task.WaitAll instead that awaits all tasks to complete.
Tasks that are never checked/blocked properly cause all sorts of wonderful things to happen and as you return a task via WhenAll it's likely this that is causing the issue. Either do something with the returned Task or switch to WaitAll - which is what I'd of expected to see
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
来源:https://stackoverflow.com/questions/53819009/thread-was-being-aborted-error-when-making-a-service-call-from-async-method