I've had a look around for some documentation, and all the documentation appears to suggest the following...
- PLINQ tasks do not have a default timeout
- PLINQ tasks can deadlock, and .NET/TPL will never cancel them for you to release the deadlock
However, in my application, this is not the case. I cannot replicate a minimal example using a simpler console app, but I will show the closest reproduction I have tried, and the actual PLINQ query that is being cancelled prior to completion. There is no Exception
of any type other than the Task Cancellation Exceptions, which all suggest that the task was requested to be cancelled directly (no other Exception
occurred anywhere). There is no cancellation code anywhere in my application, so it can only be .NET deciding to cancel it for me?
I am aware that these examples below hammer out HttpClient
s, this is not the cause, as the console example shows.
Attempt at reproduction, this code never cancels, despite the epic running time:
var j = 0;
var ints = new List<int>();
for (int i = 0; i < 5000; i++) {
ints.Add(i);
};
ints.AsParallel().WithExecutionMode(ParallelExecutionMode.ForceParallelism).WithDegreeOfParallelism(8).ForAll(n => {
int count = 0;
while (count < 100 && j == 0) {
var httpClient = new HttpClient();
var response = httpClient.GetStringAsync("https://hostname/").GetAwaiter().GetResult();
count++;
Thread.Sleep(1000);
}
});
But this code, usually gets a couple of minutes in before stalling. I'm not sure whether it stalls first, and then .NET notices this and cancels it (but that violates point 2...) or whether .NET just cancels it because it took overall too long (but that's point 1...). usernames
contains 5000 elements in the running code, hence the console test with 5000 elements. Papi
just wraps HttpClient and uses SendAsync
to send HttpRequestMessage
off, I can't see SendAsync
being the cause though.
importSuccess = usernames.AsParallel().WithExecutionMode(ParallelExecutionMode.ForceParallelism).WithDegreeOfParallelism(8).All(u => {
var apiClone = new Papi(api.Path);
apiClone.SessionId = api.SessionId;
var userDetails = String.Format("stuff {0}", u);
var importResponse = apiClone.Post().WithString(userDetails, "application/json").Send(apiClone.SessionId).GetAwaiter().GetResult();
if (importResponse.IsSuccessStatusCode) {
var body = importResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult().ToLower();
if (body == "true") {
return true;
}
}
return false;
});
Again the above PLINQ query throws a Task Cancelled Exception after a couple of minutes, no other Exception is observed. Anyone ever had a PLINQ query be cancelled without writing the cancellation themselves or know why this might be?