1

我编写以下代码来尝试使用 TaskScheduler。函数内的任务内容UpdateStatus需要在主线程上运行。但我只是得到输出表明它在单独的线程上运行。

关于原因的任何想法?或在主线程上下文中从后台线程写入状态的替代方法。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
  class Test
  {
    TaskScheduler scheduler;
    public void Run()
    {
      SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
      scheduler = TaskScheduler.FromCurrentSynchronizationContext();
      Console.WriteLine("Start on {0}", Thread.CurrentThread.ManagedThreadId);
      Task.Factory.StartNew(() =>
      {
        for (int i = 0; i < 10; i++)
        {
          Console.WriteLine("running on {0}", Thread.CurrentThread.ManagedThreadId);
          UpdateStatus(string.Format("Message {0}", i));
          Thread.Sleep(1000);
        }
      }).ContinueWith(_ =>
      {
        Console.WriteLine("complate");
        Console.WriteLine("running on {0}", Thread.CurrentThread.ManagedThreadId);
      }, new CancellationToken(), TaskContinuationOptions.None, scheduler).Wait();
    }

    private void UpdateStatus(string message)
    {
      Task.Factory.StartNew(() =>
      {
        Console.WriteLine("updating status on {0}", Thread.CurrentThread.ManagedThreadId);
        Console.WriteLine(message);
      }, new CancellationToken(), TaskCreationOptions.None, scheduler);
    }
  }

  class Program
  {
    public static void Main(string[] args)
    {
      var test = new Test();
      test.Run();
    }
  }
}
4

2 回答 2

1

Default SynchronizationContext(您正在使用)不会让您进入主线程。请参阅为什么 SynchronizationContext 无法正常工作?.

正如 svick 所提到的,在您的情况下(控制台应用程序),通常不需要主线程的概念。

于 2013-04-01T14:25:45.097 回答
0

你没有解释你到底想做什么,所以很难就最好的行动方案给你建议。

您当前的代码不起作用,因为SynchronizationContext您正在创建的代码实际上并没有进行任何同步。(而且你的主线程在Wait()调用时也被阻塞了,所以没有其他东西可以在它上面运行。)

可以使用与主线程正确同步的同步上下文(例如Nito AsyncEx中的同步上下文),但我不确定这是否是您的最佳方式。

我认为更好的方法是使用生产者/消费者模式,使用BlockingCollection. 您Task的 s 将向其中添加项目,您的主线程将从那里获取它们并使用 . 将它们发送到管道WriteObject()

于 2013-04-01T16:31:19.517 回答