Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 线程数较大时不会触发事件_C#_.net_Multithreading_Events_Delegates - Fatal编程技术网

C# 线程数较大时不会触发事件

C# 线程数较大时不会触发事件,c#,.net,multithreading,events,delegates,C#,.net,Multithreading,Events,Delegates,我在C#中使用多线程和事件委托时遇到问题。如果有人能帮我解决这个问题,那就太好了。问题在于多个线程和事件。在单个线程或最多10个线程中,自定义事件会正确触发并正常工作。但是,当我将线程数增加到15或20时,事件根本不会被触发。下面是一段示例代码: LegacyMemberStream memberStream=new LegacyMemberStream(); memberStream.OpenStream(); legacyMemberStrm = (LegacyMemberStream)me

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

LegacyMemberStream memberStream=new LegacyMemberStream();
memberStream.OpenStream();
legacyMemberStrm = (LegacyMemberStream)memberStream;                
legacyMemberStrm.ThreadErrorOccur += OnParserThreadInterrupt;
以下是OnParserThreadInterrupt()的代码:

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

parserThreads[i].OnThreadError = HandleThreadError;
parserThreads[i].StartThread();
此方法只是初始化请求的线程数,并在异常发生时为每个线程分配事件,最后启动线程

LegacyMemberStream中的HandletThreadError方法是:

 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();
            }
        }
对于任意数量的线程,从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);
                }
            }
        }
已跳过对ThreadErrorOccess的调用 因为if语句是假的

为什么这与线程数有关?我认为这是个概率问题。可能创建多个线程需要足够的时间,因此主线程上下文切换,然后线程运行(也在它们之间切换上下文),得到错误。。。所有这些都发生在主线程之前,whci创建它们时有机会执行订阅threadErrorOccess事件的行
希望它能解决您的问题。

当您看到错误处理程序被触发时,它是否会在运行应用程序后立即发生?我的回答帮助您解决了上述问题,您会接受吗?非常好。谢谢你,拉米。事实上,改变顺序解决了问题。
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);
                }
            }
        }