从thread1调用方法到thread2?

时间:2018-07-04 05:58:51

标签: c# multithreading synchronizationcontext

首先:我想做什么?

  1. 我想在一个线程上运行多个作业,例如,我想为计算创建一个线程,并始终在其中运行方法。

  2. 获取类似SynchronizationContext.Current或Thread.CurrentThread的指针以访问当前作业。

3。一种类似于Net Standard的跨平台方式。

第二个:示例1(跨平台工作)我的示例不起作用,因为SynchronizationContext中的Post和Send方法不起作用

 class Program
{
    static void Main(string[] args)
    {
        SynchronizationContext contextThread1 = null;
        SynchronizationContext contextThread2 = null;
        Thread thread1, thread2 = null;
        thread1 = new Thread(() =>
        {
            SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
            contextThread1 = SynchronizationContext.Current;
            while (true)
            {
                Thread.Sleep(1000);
                if (contextThread2 != null)
                {
                    contextThread2.Post((state) =>
                    {
                        //Thread.CurrentThread == thread2 always false because the method is not runnig from thread 2
                        Console.WriteLine("call a method from thread 1 for thread 2 :" + (Thread.CurrentThread == thread2));
                    }, null);
                }
            }
        });
        thread1.IsBackground = true;
        thread1.Start();

        thread2 = new Thread(() =>
        {
            SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
            contextThread2 = SynchronizationContext.Current;
            while (true)
            {
                Thread.Sleep(1000);
                if (contextThread1 != null)
                {
                    contextThread1.Post((state) =>
                    {

                        //Thread.CurrentThread == thread1 always false because the method is not runnig from thread 1
                        Console.WriteLine("call a method from thread 2 for thread 1 :"+(Thread.CurrentThread == thread1));
                    }, null);
                }
            }
        });
        thread2.IsBackground = true;
        thread2.Start();

        Console.ReadKey();
    }
}

示例2 :(由于Windowsbase.dll,没有交叉PLatform):此示例运行良好,但它不是跨平台的。

    class Program
{
    static void Main(string[] args)
    {
        Dispatcher contextThread1 = null;
        Dispatcher contextThread2 = null;

        Thread thread1, thread2 = null;
        thread1 = new Thread(() =>
        {
            contextThread1 = Dispatcher.CurrentDispatcher;
            Dispatcher.Run();
        });
        thread1.IsBackground = true;
        thread1.Start();

        thread2 = new Thread(() =>
        {
            contextThread2 = Dispatcher.CurrentDispatcher;
            Dispatcher.Run();
        });
        thread2.IsBackground = true;
        thread2.Start();

        while (true)
        {
            Thread.Sleep(1000);
            if (contextThread2 != null)
            {
                contextThread2.Invoke(new Action(() =>
                {
                    //Thread.CurrentThread == thread2 always false because the method is not runnig from thread 2
                    Console.WriteLine("call a method from thread 1 for thread 2 :" + (Thread.CurrentThread == thread2));
                }));
            }
            if (contextThread1 != null)
            {
                contextThread1.Invoke(new Action(() =>
                {
                    Console.WriteLine("call a method from thread 2 for thread 1 :" + (Thread.CurrentThread == thread1));
                }));
            }
        }
        Console.ReadKey();
    }
}

1 个答案:

答案 0 :(得分:3)

这些天,您应该始终使用工具来尽可能简化您的生活。在这种情况下,您应该使用Microsoft的Reactive Framework。只需NuGet“ System.Reactive”并添加using System.Reactive.Linq;

然后您可以执行以下操作:

void Main()
{
    var thread1 = new EventLoopScheduler();
    var thread2 = new EventLoopScheduler();

    Action action = () => Console.WriteLine(Thread.CurrentThread.ManagedThreadId);

    action();

    thread1.Schedule(action);

    Thread.Sleep(1000);

    thread2.Schedule(action);

    Thread.Sleep(1000);

    thread2.Schedule(() =>
    {
        action();
        thread1.Schedule(action);
    });

    Thread.Sleep(1000);

    action();
}

我得到的输出是:

11
12
14
14
12
11

如果遵循该代码,则可以看到它正在正确地调度到每个线程。

要关闭时,只需在每个.Dispose()上调用EventLoopScheduler