Is it safe to store the TaskScheduler of the UI Thread in a field as following:
class TaskSchedulerReference {
private readonly _uiTaskScheduler;
// Constructor is called by the UI Thead
public TaskSchedulerReference() {
_uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext()
}
public TaskScheduler UiTaskScheduler { get { return _uiTaskScheduler; } }
}
...so that it is possible to notify the UI at any time from any background thread in a Task.ContinueWith(action, TaskSchedulerReference.UiTaskScheduler)
callback.
Is it guaranteed that the reference remains valid during the whole application life-cycle?
Apart from that dubious // This class is first visited by the UI Thread
, yes. Use an explicit initializer (explicitly run from the UI thread) instead, the JIT is not guaranteed to run the class initializer on the UI thread.
However, I prefer capturing the context as a local variable. Exposing anything as global state is tricky in multi-threading (and asynchronous programming). Always try using as local a state as possible. It also reeks of the old IsInvokeRequired
pattern. Every method should be very explicit about what happens where - it's very easily to accidentally introduce re-entrant code and deadlocks otherwise.
If you look at the code for FromCurrentSynchronizationContext
you can see that it creates a SynchronizationContextTaskScheduler
by capturing SynchronizationContext.Current
.
As long as you do that on the UI thread you would capture the UI's SC and SynchronizationContext.SetSynchronizationContext(context)
can't change your captured context.
Note that what you store is a TaskScheduler
that holds the SC and not the SC itself. If you want to capture the SC just use SynchronizationContext.Current
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.