C#多个线程执行同一个方法,如何实现类似队列形式的一个一个的执行,防止同一时间被多个线程执行,因为这个方法设计到与外部通信,每个信号都需要4s之内给予回复,求有解决方法的人顶楼

解决方案 »

  1.   

    lock statement
    https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement
      

  2.   

    就是用lock了,但是每个请求都要4秒,如果有10个线程,最后一个线程可能要堵塞 40s才会得到响应
    static object lockObj = new object();
    public void Communicate()
    {
        lock (lockObj)
        {
            DoCommunicate();
        }
    }
      

  3.   

    用生产者消费者模式 BlockingCollection<HttpApiUploadInfo> ProcessQueue = new BlockingCollection<HttpApiUploadInfo>();
    ... 
                           ProcessQueue.Add(new HttpApiUploadInfo
                            {
    ...
                            });
    ...        void StartHttpApiInterfaceCommitLoop()
            {
                ThreadPool.QueueUserWorkItem(obj =>
                {
                    while (true)
                    {
                        foreach (HttpApiUploadInfo uploadInfo in ProcessQueue.GetConsumingEnumerable())
                        {
                            Thread.Sleep(100);                        CurrentHttpAPITaskCount = ProcessQueue.Count();                        if (uploadInfo.uploadStyle == EHttpApiUploadStyle.Packing)
                            {
    ...
                            }
                        }
                    }
                });
            }
      

  4.   

    如果处理过程相互允许并行,则   void StartHttpApiInterfaceCommitLoop()
            {
                ThreadPool.QueueUserWorkItem(obj =>
                {
                    while (true)
                    {
                        foreach (HttpApiUploadInfo uploadInfo in ProcessQueue.GetConsumingEnumerable())
                        {
                            Thread.Sleep(100);
     
                            CurrentHttpAPITaskCount = ProcessQueue.Count();
     
                            if (uploadInfo.uploadStyle == EHttpApiUploadStyle.Packing)
                            {
                                   // 开线程并行
                                    new Thread(new ParameterizedThreadStart(ProcessPackingUpload)).Start(uploadInfo);
                                   或
                                  // 排队执行
                                  ProcessPackingUpload 
                            }
                        }
                    }
                });
            }
      

  5.   

    也可以用如下代码,10秒内拿不到锁,就取消通信:static object lockObj = new object();
    public void Communicate()
    {
        if (Monitor.TryEnter(lockObj, TimeSpan.FromSeconds(10)))
        {
            try
            {
                DoCommunicate();
            }
            finally
            {
                Monitor.Exit(lockObj);
            }
        }
        else
        {
            // 获取锁失败
        }
    }
    其实比较好的作法是2端通过消息队列来通信,这样不至于出现线程死锁 或 阻塞的问题。
      

  6.   

    你可以试试Task,顺序执行任务。
      

  7.   

    lock(object){}Task.Run()
      

  8.   

    用消息队列的方式来解决这个问题,可以用redis来做消息队列
      

  9.   


    消息队列是用来并发的,不是用来阻塞的。不要见到“队列”两个字儿就望文生义。对于.net 的进程内编程,“队列”这个词儿也是比较多余的。因为 .net 有很好的机制来直接用在线程同步上,或者线程池调度上,用不着自己发明什么简单队列(何况自己发明的机制还缺少基本功能)。
      

  10.   

    用lock方式
      

  11.   

    你的意思应该是想执行多线程, 但多线程中的某一个操作是不可同时执行对不对?
    这种情况用严格的单例模式就好了:
    https://www.cnblogs.com/xmfdsh/p/4036927.html
      

  12.   

    Lock和生产都消费都不能保证进程按顺序执行
      

  13.   

    举一个例子,我们要封装一个设备的操作(随便写的)public class 投资直通车
    {
        public void 投资(string 服务种类代码, .....)
        {
             .......
        }    public event Action<定时投资反馈Argument> Alert;
        public class 定时投资反馈Argument
        {
            public ..... 时间;
            public ..... 服务种类;
            public ....  状态;
            public ....  Summary;
        }
        ........
    }那么这个投资行为里边的逻辑可能很复杂,里边可能会不定时地抛出业务事件。假设你说因为内部逻辑可能复杂、可能后期有变化,所以你就只能想到这种——所有的使用的用户端必须阻塞住“一个一个地执行”——的方式,这其实往往就降低了系统几十倍甚至上百倍效率,而且其实也不符合业务领域成熟的管理经验。就好像非常大的医院的取药窗口,肯定就比小社区医院更“聪明”一点,不会以排队为主,而是异步地交单、取药。
      

  14.   

    虽然我不知道你想干嘛,
    不过用Lock就可以了。
      

  15.   

    如果外部回信只能单线程一个一个处理,楼上那些说让他异步多线的不都是枉然~~~~~
    如果外部也是自己搞的,用消费者生产者模型就可以了吧,BlockingCollection  可以设置并行的线程数
      

  16.   

    这个贴子好,收藏!慢慢学习!
    不过如果我做这个,我用采用PLC思维,用Timer+Swith Case方式做轮询判断,第一个条件满足,再去反复判断下一个case。
    这个方法不是我发明的,大家不要喷我,但这是一个好方法。