第一:我想做什么?
我想在一个线程上运行多个作业,例如,我想创建一个用于计算的线程,并始终在其中运行方法。
获取像 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/