简体   繁体   English

.NET中的TaskScheduler.FromCurrentSynchronizationContext()

[英]TaskScheduler.FromCurrentSynchronizationContext() in .NET

I am getting a runtime exception trying to run the example below. 我试图运行下面的示例时遇到运行时异常。

Unhandled Exception: System.InvalidOperationException: The current SynchronizationContext may not be used as a TaskScheduler.
   at System.Threading.Tasks.SynchronizationContextTaskScheduler..ctor()
   at System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext()
   at TaskDemo.MyForm..ctor() in D:\myStudio\ASPNet\CSharp\CSharp4\MyApp\MyApp\Hello.cs:line 428
   at TaskDemo.SynchronizationContextTaskScheduler() in D:\myStudio\ASPNet\CSharp\CSharp4\MyApp\MyApp\Hello.cs:line 396
   at TaskDemo.Go() in D:\myStudio\ASPNet\CSharp\CSharp4\MyApp\CLRviaCSharp\Hello.cs:line 214
   at ComputeOps.Main() in D:\myStudio\ASPNet\CSharp\CSharp4\MyApp\CLRviaCSharp\Hello.cs:line 23

Code sample: 代码示例:

public class TaskSchedulerTest {

    public void Test() {
        SynchronizationContextTaskScheduler();
    }

    private void SynchronizationContextTaskScheduler() {
        var f = new MyForm();
        System.Windows.Forms.Application.Run();
    }

    private sealed class MyForm : System.Windows.Forms.Form {
        public MyForm() {
            Text = "Synchronization Context Task Scheduler Demo";
            Visible = true; Width = 400; Height = 100;
        }

        private readonly TaskScheduler m_syncContextTaskScheduler =
           TaskScheduler.FromCurrentSynchronizationContext();

        private CancellationTokenSource m_cts;

        protected override void OnMouseClick(System.Windows.Forms.MouseEventArgs e) {
            if (m_cts != null) {    // An operation is in flight, cancel it
                m_cts.Cancel();
                m_cts = null;
            } else {                // An operation is not in flight, start it
                Text = "Operation running";
                m_cts = new CancellationTokenSource();

                // This task uses the default task scheduler and executes on a thread pool thread
                var t = new Task<Int32>(() => Sum(m_cts.Token, 20000), m_cts.Token);
                t.Start();

                // These tasks use the synchronization context task scheduler and execute on the GUI thread
                t.ContinueWith(task => Text = "Result: " + task.Result,
                   CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion,
                   m_syncContextTaskScheduler);

                t.ContinueWith(task => Text = "Operation canceled",
                   CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled,
                   m_syncContextTaskScheduler);

                t.ContinueWith(task => Text = "Operation faulted",
                   CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted,
                   m_syncContextTaskScheduler);
            }
            base.OnMouseClick(e);
        }
    }
}

Any idea? 任何的想法?

put the creation of m_syncContextTaskScheduler into your form constructor . m_syncContextTaskScheduler的创建放入表单构造函数中。

public MyForm() {
    Text = "Synchronization Context Task Scheduler Demo";
    Visible = true; Width = 400; Height = 100;
    m_syncContextTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
}

Thanks! 谢谢! It works, what is the reason behind it? 它有效,它背后的原因是什么?

Because the constructor initializes the readonly members that have an initializer too soon. 因为构造函数很快初始化具有初始化程序的只读成员。 The Form class constructor installs the synchronization provider if needed, an instance of a class named WindowsFormsSynchronizationContext. 如果需要,Form类构造函数安装同步提供程序,即名为WindowsFormsSynchronizationContext的类的实例。 The C# compiler generates the code for readonly initializers before calling the base class constructor. 调用基类构造函数之前 ,C#编译器为readonly初始化程序生成代码。 Moving the assignment into the constructor body ensures that it is initialized after calling the base constructor. 将赋值移动到构造函数体中可确保调用基础构造函数初始化它。

Be careful with readonly member initializers, keep them simple. 注意只读成员初始化程序,保持简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 TaskScheduler.FromCurrentSynchronizationContext块UI - TaskScheduler.FromCurrentSynchronizationContext block ui TaskScheduler.Current和TaskScheduler.FromCurrentSynchronizationContext()的区别? - TaskScheduler.Current and TaskScheduler.FromCurrentSynchronizationContext() difference? 使用TaskScheduler.FromCurrentSynchronizationContext更新Task中的UI - update UI in Task using TaskScheduler.FromCurrentSynchronizationContext TaskScheduler.FromCurrentSynchronizationContext()是否表示该类的上下文? - Does TaskScheduler.FromCurrentSynchronizationContext() mean the context of the class? 为什么TaskScheduler.FromCurrentSynchronizationContext在Monotouch中不同步? - Why doesn't TaskScheduler.FromCurrentSynchronizationContext synchronize in Monotouch? 从工作线程调用TaskScheduler.FromCurrentSynchronizationContext异常 - TaskScheduler.FromCurrentSynchronizationContext exception when called from worker thread Async / Await等效于带有CancellationToken和TaskScheduler.FromCurrentSynchronizationContext()调度程序的.ContinueWith - Async/Await equivalent to .ContinueWith with CancellationToken and TaskScheduler.FromCurrentSynchronizationContext() scheduler 关于TaskScheduler.FromCurrentSynchronizationContext和Task.Factory.StartNew()的使用 - Regarding usage of TaskScheduler.FromCurrentSynchronizationContext & Task.Factory.StartNew() 我如何使用TaskScheduler.FromCurrentSynchronizationContext()解决后台线程异常上的UI更新 - how do i use TaskScheduler.FromCurrentSynchronizationContext() to solve UI update on background thread exception Task.ContinueWith(...,TaskScheduler.FromCurrentSynchronizationContext())在UI线程上运行的任何场景? - Any scenario where Task.ContinueWith(…, TaskScheduler.FromCurrentSynchronizationContext()) would *not* run on the UI thread?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM