You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Message: 'Start may not be called on a task that has completed.',
Stack: ' at System.Threading.Tasks.Task.Start(TaskScheduler scheduler)
at LinqToDB.AsyncExtensions.GetTask[T](Func`1 func, CancellationToken token)
at LinqToDB.AsyncExtensions.ToArrayAsync[TSource](IQueryable`1 source, CancellationToken token)
Regarding AsyncExtensions functions that create tasks, I agree they could all be removed in favor of Task.Run() overloads, which should be avail. since .net 4.5?
BTW I believe your exception arises when calling Start() on a task that was created with a cancellation token that is already cancelled when you call Start().
Because of this, using new Task(cancellationToken) when the token is not under you control and properly synchronized, is a race condition hazard and should be avoided.
RE the LinqExtensions piece of code... I have so many questions 😆
I am not sure whether the provider can possibly not be IQueryProviderAsync.
Doing sync over async is just worst than sync, I'd even prefer if the code executed sync and returned a completed Task...
I don't know the history of linq2db option ContinueOnCapturedContext and it's a weird option.
The pattern for that last point is unlike general .net guidance.
Generally libraries such as linq2db should call .ConfigureAwait(false) in their async functions so that internal work is not bound to a specific scheduler (UI thread or http request thread). Application code is then free to do whatever they want at their level (which is typically nothing and awaited tasks are executed on their main thread scheduler).
I'm wondering what use is that option for, and whether it even has the intended effect?
In the code you linked, that ConfigureAwait code has almost zero effect. Note that the task created by Task.Run is not actually returned by DeleteAsync but awaited. DeleteAsync itself is an async function, so it'll return another Task instance and the scheduler used by continuations of DeleteAsync depend on the await configuration at caller site rather than Common.Configuration.ContinueOnCapturedContext at that location... so it seems rather useless to me.
I believe your exception arises when calling Start() on a task that was created with a cancellation token that is already cancelled when you call Start().
yes, and while it is completely valid scenario, it adds one too much useless exception to ignore when we already have Task/Operation cancelled duo...
... ContinueOnCapturedContext ...
it was added in times when we had little idea about this stuff to just please everyone :). Probably it's a good idea to get rid of it in v6 finally
We should review/fix/simplify places where we create and run Tasks, e.g.
https://github.com/linq2db/linq2db/blob/master/Source/LinqToDB/AsyncExtensions.cs#L30-L68
this leads to exceptions like:
https://github.com/linq2db/linq2db/blob/master/Source/LinqToDB/LinqExtensions.cs#L732-L735
this is not necessary, as we should always work with
IQueryProviderAsync
The text was updated successfully, but these errors were encountered: