当线程数很大时,不会触发事件

时间:2015-07-27 17:21:44

标签: c# .net multithreading events delegates

我在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()事件。我无法理解为什么在线程数增加时不会触发事件。

1 个答案:

答案 0 :(得分:2)

基于您共享的此代码,似乎可能的唯一原因是错误发生在您提交事件处理程序之前。所以只需改变第一行的顺序:

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事件的行 希望它能解决你的问题。