Parallel dev: .NET SynchronizationContext 二三事

原文地址:https://msdn.microsoft.com/magazine/gg598924.aspx


今天开发遇到一个问题,stack overflow上有很简单的解决办法,但是我同事发现用那个解决办法有可能导致ui操作无法在ui线程上执行。

具体问题如下:

1. TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
//TaskScheduler scheduler = TaskScheduler.Default;
2. SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
3. Task.Factory.StartNew(action).ContinueWith(result, scheduler);
scheduler是干嘛的? 可以不要吗
FromCurrentSynchronizationContext报错,察看当前context: System.Threading.SynchronizationContext.current 是第三方的Context
导致报错,can't be used as a scheduler


MSDN 上有篇文章

Parallel Computing - It's All About the SynchronizationContext

恰好是关于这个主题的,摘抄重点如下:

ISynchronizeInvoke --> SynchronizationContext
ISynchronizeInvoke: 1. determining if synchronization was necessary
 2. queue uow from one thread to another
SynchonizationContext: 1. queue uow to a context
 2. no way to determining if synchronization is necessary
 3. keeps count of outstanding asynchronous operations
 
Thread: 1. have a "current" context
2. its context is not necessarily unique
3. it's possible to change thrad's current context

Single UI threads: all delegates queued to them are executed one at a time by a specific UI thread in the order they were queued.
WindowsFormsSynchronizationContext 
DispatcherSynchronizationContext 


Default(ThreadPool)SynchronizationContext: if current context is null, then it has a default context. It's also implicitly applied to child threads 
unless the child thread sets its own context.Thus, UI applications usually have two synchronization contexts: the UI SynchronizationContext covering the UI thread, and the default SynchronizationContext covering the ThreadPool threads
https://i-msdn.sec.s-msft.com/dynimg/IC468121.jpg


https://i-msdn.sec.s-msft.com/dynimg/IC468122.jpg
BackgroundWorkers do not have to run in UI Context!!!


SynchronizationContext provides a means for writing components that may work within many different frameworks. BackgroundWorker and WebClient are two examples that are equally at home in Windows Forms, WPF, Silverlight, console and ASP.NET apps.


Not all SynchronizationContext guarantee the order of delegate execution or synchronization of delegates. UI-based context do satisfy these conditions.
it’s best to not assume that any context instance will run on any specific thread


event-based asynchronous pattern VS task-based asynchronous pattern


when re-entrancy is desired, such as a client invoking a server method that invokes a client callback.


Task Parallel Library: TaskScheduler.FromCurrentSynchronizationContext and CancellationToken.Register
default TaskScheduler works like default context.
Figure 5 Progress Reporting with UI Updates


private void button1_Click(object sender, EventArgs e)
{
  // This TaskScheduler captures SynchronizationContext.Current.
  TaskScheduler taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
  // Start a new task (this uses the default TaskScheduler, 
  // so it will run on a ThreadPool thread).
  Task.Factory.StartNew(() =>
  {
    // We are running on a ThreadPool thread here.

  
    ; // Do some work.

  // Report progress to the UI.
    Task reportProgressTask = Task.Factory.StartNew(() =>
      {
        // We are running on the UI thread here.
        ; // Update the UI with our progress.
      },
      CancellationToken.None,
      TaskCreationOptions.None,
      taskScheduler);
    reportProgressTask.Wait();
  
    ; // Do more work.
  });
}


Figure 4 Summary ofSynchronizationContext Implementations

 

Specific Thread Used to Execute Delegates

Exclusive (Delegates Execute One at a Time)

Ordered (Delegates Execute in Queue Order)

Send May Invoke Delegate Directly

Post May Invoke Delegate Directly

Windows Forms

Yes

Yes

Yes

If called from UI thread

Never

WPF/Silverlight

Yes

Yes

Yes

If called from UI thread

Never

Default

No

No

No

Always

Never

ASP.NET

No

Yes

No

Always

Always

你可能感兴趣的:(线程,C#,parallel)