TaskCompletionSource.SetResult() executes on the same thread as the waiting one [Answered]
Hey, as the title already says I've found a deadlock in my code and would like to understand it.
To give you an example:
So why is the awaited method continuing on the thread that called
TrySetResult
?17 Replies
❯ Enum: System.Threading.Tasks.TaskCreationOptions
Specifies flags that control optional behavior for the creation and execution of tasks.
❯ Field: System.Threading.Tasks.TaskCreationOptions.None
Specifies that the default behavior should be used.
❯ Field: System.Threading.Tasks.TaskCreationOptions.LongRunning
Specifies that a task will be a long-running, coarse-grained operation involving fewer, larger components than fine-grained systems. It provides a hint to the TaskScheduler that oversubscription may be warranted. Oversubscription lets you create more threads than the available number of hardware threads. It also provides a hint to the task scheduler that an additional thread might be required for the task so that it does not block the forward progress of other threads or work items on the local thread-pool queue.
3/8 results shown ~ Click Here for more results
React with ❌ to remove this embed.
You want the
RunContinuationsAsynchronously
Thanks that works
But could you also explain why it continues on the thread setting the result, not the calling/currently waiting thread?
Sorry, on mobile currently
@Dusty
!nothread
hm?
$nothread
There Is No Thread
This is an essential truth of async in its purest form: There is no thread.
Is why
Sorry was looking for the tag syntax
Because there is no thread associated with the callback
I know that, it just makes no sense for me why my task switches the thread to the thread which sets the result
Well yea but why does it always resume on the same thread? I'd like to understand that
If you don't have multiple tasks running then almost certainly because there's no reason to create another execution thread
But why is there event a switch then?
likely because there is no synchronization context to pin the async method to a specific thread
by default async methods can be executed on effectively any thread, without any guarantees
in cases where there is a need, synchronization context and/or task scheduler is used to enforce where the task should be executed
but again, you should avoid writing your async methods in a way that requires them to be executed on specific threads (where possible) as it can degrade your app's performance
So that means it could also be another thread from the thread pool in theory but it uses the same thread as the runtime thinks that the thread is not needed at that moment?
Well I have a separate thread for my message loop which needs to run in parallel with everything else.
From that message loop thread I set the result, so the solution you sent me earlier is okay or is there anything else or bad about it? The only restriction I have for that async method is that it shouldn't run on the message loop thread
it uses the same thread as the runtime thinks that the thread is not needed at that moment?no, because by default continuations (i.e. code waiting for the task's completion) execute synchronously with the task's completion (i.e.
SetResult()
in your case). IF you had a sync context (e.g. how UI frameworks behave), it would've pushed the continuation to that sync context (which would've likely forwarded the execution to some other thread)
nope, RunContinuationsAsynchronously
is precisely made for this purpose. It means "send all continuations to the thread pool, regardless of how they are setup internally"
so the only cost that you are paying (on your message loop thread) is the queuing to the TP, but that's basically freeAh i see
Then thank you for the explanation and solution!
✅ This post has been marked as answered!