请问C# 多线程间如何传递消息方便些?

vc_learner 2016-06-07 04:11:47
之前用 VC ,用 PostThreadMessage 和 GetMessage 就可以 ;
但是在C#里用这样两个,要通过各种转化才得到所需数据,感觉很不方便 ;

搜了半天,没有发现合适的方案;

其实我就想实现如下:
主线程接收到相关输入后,将特定消息发给不同的子线程,由子线程作具体处理 ;
同时我也希望子线程在没有数据时处于休眠状态,不占CPU ,类似 VC 语言里的 GetMessage ();
并且子线程能逐个处理消息。


请问各位有没有好的方案推荐,或者给个思路;谢谢


...全文
1503 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
fazl 2018-05-05
  • 打赏
  • 举报
回复
引用 8 楼 qq64765940 的回复:

    public class MessageEventWaitHandle<T> : EventWaitHandle
    {
        private T message;

        public MessageEventWaitHandle(bool initialState, EventResetMode mode)
         : base(initialState, mode)
        {
        }

        public bool Set(T message)
        {
            this.message = message;
            return base.Set();
        }

        public T GetMessage()
        {
            return this.message;
        }
    }
不用谢,高兴的话,赏点分!!!
很好用,改一下加个自动清空消息就更好用了
bluk44444 2018-01-15
  • 打赏
  • 举报
回复
//申明信号灯 AutoResetEvent autoEvent = new AutoResetEvent(false);   //使用信号灯 public void Test() { autoEvent.WaitOne(); //dosomething autoEvent.Reset(); //递归调用 Test(); }
SoulRed 2018-01-11
  • 打赏
  • 举报
回复
共享内存,socket 。都可以,而且不止于多线程间通信,更能达到跨进程或者跨服务器通信。 当然,效率有点低,如果要追求单程序高效率线程通信,那么建议用委托之类的
秋的红果实 2018-01-11
  • 打赏
  • 举报
回复
其实我就想实现如下: 主线程接收到相关输入后,将特定消息发给不同的子线程,由子线程作具体处理 ; 同时我也希望子线程在没有数据时处于休眠状态,不占CPU ,类似 VC 语言里的 GetMessage (); 并且子线程能逐个处理消息。 ==> .NET已经封装了很多基础实现,例如你提到的VC内容。 你的需求,主线程开出处理子线程后,自然就“空闲”了,真正的处理在子线程。 所谓的通讯,就你的问题,只要处理子线程执行完,执行回调函数即可,委托里封装的多线程机制就可以实现,搜索IAsyncResult
xuzuning 2018-01-10
  • 打赏
  • 举报
回复
子线程中能响应消息吗? 怎么我看到的资料中都说 C# 的子线程是没有消息循环的。孤陋了?
_瑶瑶_ 2018-01-10
  • 打赏
  • 举报
回复

    public class MessageEventWaitHandle<T> : EventWaitHandle
    {
        private T message;

        public MessageEventWaitHandle(bool initialState, EventResetMode mode)
         : base(initialState, mode)
        {
        }

        public bool Set(T message)
        {
            this.message = message;
            return base.Set();
        }

        public T GetMessage()
        {
            return this.message;
        }
    }
不用谢,高兴的话,赏点分!!!
sgyiliya 2016-06-08
  • 打赏
  • 举报
回复
2楼说的对呀。 你的特定消息不可能是无限多种类型吧,如果是5种特定消息,定义好5个class来放这些特定消息, 然后在每次收到特定消息时候,开启一个新的线程,把这些参数发送给这个新的线程即可,该线程执行完后自动销毁,仅在生命期间占用资源。


public class MyParams//这里存放特定消息
        {
            public string IP;
        }

MyParams _MyParams = new MyParams();
            _MyParams.IP = "192.168.226.1";
Thread MyPing = new Thread(new ParameterizedThreadStart(CmdPing));
            MyPing.IsBackground = true;
            MyPing.Start(_MyParams);

private static string CmdPing(object str)
        {
            MyParams _theip = str as MyParams;
_theip.IP.Trim()//这里取出实际要接收的参数。
}
zs808 2016-06-08
  • 打赏
  • 举报
回复
关于多线程的数据传输,可以通过自定义消息队列的形式实现。在.NET中已经实现了一个基于内存的线程安全队列ConcurrentQueue<T>。主线程可以向不同的消息队列中入队列数据,然后响应的线程从对应队列中出队列数据来进行操作。 关于休眠,如果当前线程的队列数据为空,则进行休眠操作,推荐使用Thread.Sleep(1)方法来实现,不要使用Thread.SpinWait(1)来进行休眠,因为Sleep不抢占CPU,节省系统资源。
Forty2 2016-06-08
  • 打赏
  • 举报
回复
引用 楼主 vc_learner 的回复:
... 其实我就想实现如下: 主线程接收到相关输入后,将特定消息发给不同的子线程,由子线程作具体处理 ; 同时我也希望子线程在没有数据时处于休眠状态,不占CPU ,类似 VC 语言里的 GetMessage (); 并且子线程能逐个处理消息。
其实C#下可以更简单: 主线程接收到相关输入后,启动工作线程具体处理。 工作线程开始前,结束后,自然不占用CPU。
  • 打赏
  • 举报
回复 1
我们来看”生产者-消费者“模式后边是什么,就能知道为什么许多人空谈”队列“反而会瞎扯。 生产者、消费者模式本身没有什么问题,它就是一个模式而已。它就好像是”星型“总线,用来收集各方的接入这个模式本来没有问题。但是在消费处理端是什么?消费处理端最终是多进程、多线程、用卫星机集群去并发处理的!”生产者-消费者“模式本身是一个队列,两端都是并发多个处理机。如果有人说”消费者“只是一个线程,这不就是瞎扯了嘛,这样的人根本没有搞懂消费者模型,也没有搞懂多线程并发处理程序的设计。 你用c 或者 java 来搞这类编程,你有没有想过要自己写一个”线程池“然后再来应用到各种低级的业务中?如果有,你就不会有什么”子线程诸葛进行处理“这种说法了。如果遇到并发多线程处理的设计问题,不管你遇到的是c++、java 还是 .net 平台开发者,你就问他一句话“你写过或者用过线程池吗?” 如果他自己只是整什么“队列”,你就知道对方主要是个人自学书上的模式。因为凡是正规的大的团队,都有至少几十行代码写出来的“线程池”用来规范化地注册成百上千个任务的,都不是什么你自己弄“一个子线程”。
月影 2016-06-08
  • 打赏
  • 举报
回复
BlockingCollection<T>. 不用谢。
  • 打赏
  • 举报
回复 1
你的所谓的“子线程”在那里进行“死循环、阻塞、休眠、逐个处理消息”的特征,是我能想到的所有应用线程的概念中最低级的一种了。 在20年前,java中比较流行的 GOF 的书《设计模式》上写了一个“生产者-消费者模型”,在不懂事件驱动、不考虑windows系统线程独特性、图简单“的背景下,这个模式被最无脑的 java 程序员误以为是多线程编程的模式。 至少在 .net 中,线程池本身就是队列、优化、调度、复用的机制,用不着你自己去搞什么”队列“。你所要做的就是把任务注册给线程池,让其再合适的时机去并发执行。除了手动地使用系统线程池,还可以只用强大的 PLInq 来编程。而纠结与低级的编程语言、概念的人,就需要首先搞懂 .net 下的线程池 QueueUserWorkItem 操作和PLinq 的。 实际上当年我们使用 c 语言来开发国内最大的程控交换机话务软件时,我们使用了低级的c语言,但是我们模拟了整套的”面向对象、事件驱动、线程池管理、缓存管理“等等的宏。可见用 c 语言的人也不是都局限于低级的编程中。 虽然 c 语言编程语言很低级,但是如果你想去模拟高级语言的机制,还是完全可以做到的。
  • 打赏
  • 举报
回复 1
在.net中,对象之间的消息通知,可以直接给属性、直接调用方法,如果需要“依赖倒置”处理时也可以使用事件、委托的形式来通知。线程进行很短促的(例如只有几十毫秒)的工作。并发高性能的线程算法,主要靠系统线程池来优化调度线程,没有系统优化调度而自己胡乱new 线程实例是错误的做法。 你所谓的c语言,完全没有什么章法,胡乱编写一些小例子。如果做大的服务系统,还是要从头学!

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧