c# - 从thread1调用一个方法到thread2?
问题描述
第一:我想做什么?
我想在一个线程上运行多个作业,例如,我想创建一个线程进行计算并始终在其中运行方法。
获取像 SynchronizationContext.Current 或 Thread.CurrentThread 这样的指针来访问当前工作。
3.像Net Standard这样的跨平台方式。
第二: Example-1 (CrossPlatform-Working) 我的例子不起作用,因为 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
如果您遵循代码,您可以看到它正确地调度到每个线程。
当您想关闭时,只需调用.Dispose()
每个EventLoopScheduler
.
推荐阅读
- javascript - 具有不同捆绑包的 Webpack 多个入口点
- iis - IIS 默认将站点日志保留多长时间?
- postgresql - 使用带有 SSL 的 Cloud Shell 连接到 Google Cloud SQL PostgreSQL?
- php - PHP:用逗号(,)分割字符串但忽略方括号内的任何内容?
- python - 基于另一列迭代地为 Pandas 列赋值
- scala - Scala Spark udf java.lang.UnsupportedOperationException
- git - 如何通过 API 从 SonarQube 项目中检索分支信息?
- functional-programming - 错误:此表达式的类型为 int,但预期的表达式类型为 'a option
- zeromq - 为什么几乎所有 ZeroMQ 代码示例都包含 sleep() 操作?
- mysql - mysql查询最低选项总和