c# - .NET 中的 TaskScheduler.FromCurrentSynchronizationContext()

标签 c# .net task-parallel-library

我在尝试运行下面的示例时遇到运行时异常。

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

代码示例:

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);
        }
    }
}

有什么想法吗?

最佳答案

m_syncContextTaskScheduler 的创建放入您的表单构造函数中。

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

关于c# - .NET 中的 TaskScheduler.FromCurrentSynchronizationContext(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8193296/

相关文章:

c# - Task.Start 奇怪的行为

c# - Chrome 显示 keyCode 未定义

c# - 求源码.NET图像处理 "lasso"选择器

c# - 将 1,7346 舍入到 1,74

c# - 使用属性和性能

c# - Thread Join() 导致 Task.RunSynchronously 未完成

c# - 异步/等待任务,重构方法

c# - 如何将基于约定的自定义与 AutoFixture 的 [AutoData] 属性相结合?

c# - 如何检查一个列表是否包含另一个列表的所有元素

c# - 在 .NET 语言之间共享类方法