线程数大时不触发事件

Event is not triggered when number of threads is large

我在使用 C# 中的多线程和事件委托时遇到问题。如果有人能帮我解决这个问题,那就太好了。问题在于多个线程和事件。在单个线程或最多 10 个线程中,自定义事件被正确触发并且工作正常。但是,当我将线程数增加到 15 或 20 时,根本不会触发事件。这是一段代码示例:

LegacyMemberStream memberStream=new LegacyMemberStream();
memberStream.OpenStream();
legacyMemberStrm = (LegacyMemberStream)memberStream;                
legacyMemberStrm.ThreadErrorOccur += OnParserThreadInterrupt;

这是 OnParserThreadInterrupt() 的代码:

  private void OnParserThreadInterrupt(Object Sender, ThreadErrorEventArgs args)
        {
            // Exception logging is done here
        }

并且,LegacyMemberStream.OpenStream() 方法的部分是:

parserThreads[i].OnThreadError = HandleThreadError;
parserThreads[i].StartThread();

该方法简单地初始化请求的线程数,并在发生异常时为每个线程分配事件,最后启动线程。

而且,LegacyMemberStream 中的 HandleThreadError 方法是:

 public void HandleThreadError(Exception exception, string threadName)
        {

            lock (SyncObject)
            {
                Console.WriteLine("From parser thread");
                for (int i = 0; i < parserThreads.Length; i++)
                {
                    if (parserThreads[i].Name.Equals(threadName))
                    {
                        parserThreads[i].StopThread();                        
                        break;
                    }
                }

                int threadFailureErrorCode = -1111;
                OnThreadFailure(new ThreadErrorEventArgs(threadFailureErrorCode, true,exception));

               somethingQueue.StopQueuing();
            }
        }

LegacyMemberStream.OnThreadFailure:

protected virtual void OnThreadFailure(ThreadErrorEventArgs e)
        {            
            lock (_locker)
            {
                var threaderrorOccur = ThreadErrorOccur;
             //   Console.WriteLine("Exception occurred");
                if (threaderrorOccur != null)
                {
                    ThreadErrorOccur(this, e);
                }
            }
        }

对于任意数量的线程,从 OnThreadError 事件调用 HandleThreadError() 方法。

到目前为止,我从调试中发现,当线程数大于 15(或有时为 20)时,不会调用 OnParserThreadInterrupt() 方法。但是,对于相同的输入和相同的场景,当线程数较少时会触发 OnParserThreadInterrupt() 事件。我不明白为什么当线程数增加时没有触发事件。

根据您共享的这段代码,似乎唯一可能的原因是错误发生在您提交事件处理程序之前。所以只需将第一行的顺序更改为:

LegacyMemberStream memberStream=new LegacyMemberStream();
legacyMemberStrm = (LegacyMemberStream)memberStream;                
legacyMemberStrm.ThreadErrorOccur += OnParserThreadInterrupt;
memberStream.OpenStream();

如果上下文切换发生在您有机会提交事件处理程序之前,那么此函数:

protected virtual void OnThreadFailure(ThreadErrorEventArgs e)
        {            
            lock (_locker)
            {
                var threaderrorOccur = ThreadErrorOccur;
             //   Console.WriteLine("Exception occurred");
                if (threaderrorOccur != null)
                {
                    ThreadErrorOccur(this, e);
                }
            }
        }

跳过了对 ThreadErrorOccur 的调用 因为 if 语句是假的。

为什么和线程数有关?我认为这是概率问题。也许创建许多线程会消耗足够的时间,所以主线程上下文切换,然后线程 运行(也在它们之间切换上下文),得到错误......所有这些都发生在主线程之前,whci 创建它们有有机会做订阅 ThreadErrorOccur 事件的行 希望它能解决您的问题。