C#非UI跨线程调用
我正在尝试用C#进行跨线程调用 每当我从线程B调用的静态方法调用在线程A上下文中创建的对象的方法时,该方法总是在线程B中运行。我不希望这样,我希望它与我正在调用其方法的线程A对象在同一线程上运行 Invoke对于UI调用非常有效,我已经阅读了几十篇文章,因此回答了有关跨线程表单/WPF调用的不同方法。然而,无论我尝试什么(事件处理、委托等),如果线程B调用线程A的对象方法,那么它总是在线程B中运行 为了解决这个问题,我应该找图书馆的哪一部分?如果相关,线程B当前会“旋转”,从网络端口读取数据,偶尔会通过在线程a中创建并使用参数化ThreadStart传入的委托调用线程a的对象方法 我不想改变范例,只是从一个线程(线程B)向另一个线程(线程a)发送消息(调用方法的请求) 编辑:C#非UI跨线程调用,c#,multithreading,invoke,C#,Multithreading,Invoke,我正在尝试用C#进行跨线程调用 每当我从线程B调用的静态方法调用在线程A上下文中创建的对象的方法时,该方法总是在线程B中运行。我不希望这样,我希望它与我正在调用其方法的线程A对象在同一线程上运行 Invoke对于UI调用非常有效,我已经阅读了几十篇文章,因此回答了有关跨线程表单/WPF调用的不同方法。然而,无论我尝试什么(事件处理、委托等),如果线程B调用线程A的对象方法,那么它总是在线程B中运行 为了解决这个问题,我应该找图书馆的哪一部分?如果相关,线程B当前会“旋转”,从网络端口读取数据,偶
我的问题是“我应该在图书馆的哪一部分去解决这个问题?”答案似乎是否定的。如果我想清楚地描述消费和轮询,我必须编写自己的代码来处理它。你要做的是滚动一种队列,并让线程监视该队列的工作。当线程A看到新工作进入队列时,它可以将其出列并完成工作,然后返回等待更多工作 下面是一些伪代码:
public class ThreadAQueue
{
private Queue<delegate> _queue;
private bool _quitWorking;
public void EnqueueSomeWork(delegate work)
{
lock(_queue)
{
_queue.Enqueue(work);
}
}
private void DoTheWork()
{
while(!quitWorking)
{
delegate myWork;
lock(_queue)
{
if(_queue.Count > 1)
myWork = _queue.Dequeue();
}
myWork();
}
}
}
公共类ThreadAQueue
{
专用队列;
私人厕所;
公共无效排队工作(委托工作)
{
锁定(_队列)
{
_排队。排队(工作);
}
}
私有void DoTheWork()
{
当(!退出工作)
{
委派我的工作;
锁定(_队列)
{
如果(_queue.Count>1)
myWork=_queue.Dequeue();
}
我的作品();
}
}
}
每当我调用线程上运行的对象的方法时
对象不会在线程上运行
为了使其工作,您必须创建某种类型的队列,您可以将委托推入其中,该队列将定期检查线程a的主循环。类似这样,假设Something.MainThreadLoop是线程A的入口点:
public class Something
{
private Queue<Action> actionQueue = new Queue<Action>();
private volatile bool threadRunning = true;
public void RunOnThread(Action action)
{
if (action == null)
throw new ArgumentNullException("action");
lock (actionQueue)
actionQueue.Enqueue(action);
}
public void Stop()
{
threadRunning = false;
}
private void RunPendingActions()
{
while (actionQueue.Count > 0) {
Action action;
lock (actionQueue)
action = actionQueue.Dequeue();
action();
}
}
public void MainThreadLoop()
{
while (threadRunning) {
// Do the stuff you were already doing on this thread.
// Then, periodically...
RunPendingActions();
}
}
}
代码在线程上运行。对象没有(通常-请参见线程本地)绑定到特定线程。通过执行WinFormControl.Invoke或WPFControl.Invoke,您将分别向消息泵或调度程序发送一条消息,以便在以后运行一些代码 消息泵是这样的:
Message message;
while(GetMessage(&message))
{
ProcessMessage(message);
}
Microsoft专门构建了UI控件和项目,以允许跨线程发布消息。从线程a调用方法将始终在线程a上执行该方法,即使它最终执行某种异步工作并提前返回
编辑:
我认为你需要的是生产者-消费者模式
忘记从你的主线程获取消息,这听起来像是你想要做的。从线程C中消耗
线程A正在做“更重要的事情”。线程B正在旋转,侦听消息。线程C正在使用这些消息
不需要跨线程编组。编辑:我认为您可能需要使用System.Threading.AutoResteEvent类。MSDN文档中有一个很好的例子,一个线程在另一个线程上等待,我认为这与您尝试执行的操作类似: 特别要注意对trigger.WaitOne()和trigger.Set()的调用 编辑2:在阅读OP的新评论后,添加了选项#3 “每当我调用在线程A上运行的对象的方法时…”-对象不会在线程上“运行”,也不会真正属于任何线程,无论是哪个线程创建了对象 鉴于您的问题是关于“非UI跨线程调用”,我假设您已经熟悉“UI跨线程调用”。我可以看出WinForms会给您一种印象,即线程拥有一个对象,您需要向线程“发送消息”以使其执行某些操作 WinForm控件对象是一种特殊情况,因为如果与它们交互的线程不是创建它们的线程,那么它们就不能正常工作,但这不是由线程和对象交互的方式造成的 不管怎样,我们继续回答你的问题 首先,一个澄清问题的问题:您提到了线程B在做什么,但是线程a在被线程B“调用”之前在做什么 以下是一些我认为与你想做的事情大致相同的想法:
Message message;
while(GetMessage(&message))
{
ProcessMessage(message);
}