c# - 从线程1调用方法到线程2?

标签 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):此示例工作正常,但不是跨平台。

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

最佳答案

现在您应该始终使用工具来尽可能让您的生活更轻松。在这种情况下,您应该使用 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

如果您按照代码进行操作,您可以看到它正确地调度到每个线程。

当您想要关闭时,只需在每个 EventLoopScheduler 上调用 .Dispose() 即可。

关于c# - 从线程1调用方法到线程2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51166682/

相关文章:

c# - 在另一个线程上捕获异常?

c# - 作为 .NET 可执行文件中托管模块的一部分,PE header 和 CLR header 中包含什么?

java - Android NDK多线程 block UI响应

ios - GCD 对比 @synchronized 对比 NSLock

c# - 在哪里处理 Task 抛出的异常

c# - 跨线程交互C#

c# - 使用 LINQ 将日期/周列表拆分为 a 和 b 周

c# - 如何在gridviewc中获取按钮Id和字段名称

c# - EF6 和分层架构