当前位置: 首页 > 编程语言 > C#

有人可以解释一下使用ThreadPool时的这种奇怪行为吗?分享

时间:2023-04-10 17:57:45 C#

有人可以解释一下使用ThreadPool时的这种奇怪行为吗?代码使用系统;使用系统线程;publicdelegatevoidLoadingProgressCallback(doublePercentComplete,stringItemName);publicdelegatevoidLoadCompleteCallback(intItemID,stringItemName);publicstaticclassProgram{publicstaticvoidMain(string[]args){LoadTestloadTest=newLoadTest();loadTest.LoadItems(args);}}publicclassLoadTest{ManualResetEventresetEvent;int线程数=0;publicLoadTest(){}publicvoidLoadItems(string[]Items){numThreads=0;resetEvent=newManualResetEvent(false);foreach(项目中的字符串项目){Console.WriteLine("将{0}添加到线程池",item);ThreadPool.QueueUserWorkItem(delegate{Load(item,this.progCall,this.compCall);});线程数++;Thread.Sleep(100);//去掉这一行}resetEvent.WaitOne();}publicvoidprogCall(doublePercentComplete,stringItemName){Console.WriteLine("{0}:完成{1}%[THREAD:{2}]",ItemName,PercentComplete.ToString(),Thread.CurrentThread.ManagedThreadId.ToString());}publicvoidcompCall(intItemID,stringItemName){Console.WriteLine("{0}:完成",ItemName);numThreads--;if(numThreads==0){resetEvent.Set();}}publicvoidLoad(stringItem,LoadingProgressCallbackprogressCallback,LoadCompleteCallbackcompleteCallback){Console.WriteLine("加载中:{0}[THREAD:{1}]",Item,Thread.CurrentThread.ManagedThreadId.ToString());for(inti=0;i<=100;i++){if(progressCallback!=null){progressCallback((double)i,Item);}Thread.Sleep(100);}if(completeCallback!=null){completeCallback(0,Item);}}}Comments如果我从命令行运行这个程序,像这样...>TheProgramitem1item2输出将是这样的添加item1到线程池加载:item1[线程:3]item1:0%完成[线程:3]将item2添加到线程池加载:item2[线程:4]item2:0%完成[线程:4]项目1:完成1%[线程:3]项目2:完成1%[线程数:4]项目1:完成2%[线程数:3]项目2:完成2%[线程数:4]但是,如果我删除此行。Thread.Sleep(100);//从LoadItems方法中删除这一行,输出如下所示。将项目1添加到线程池将项目2添加到线程池加载:项目2[线程:4]加载:项目2[线程:3]项目2:完成0%[线程:4]项目2:完成0%[线程:3]项目2项目:1%done[Threads:4]Item2:1%done[Threads:3]Item2:2%done[Threads:3]Item2:2%done[Threads:4]问题似乎是使用了两个线程,虽然他们似乎都在使用相同的数据。为什么代码会这样?您正在关闭循环变量,这会给您带来意想不到的结果。试试这个:foreach(项目中的字符串项目){字符串项目2=项目;Console.WriteLine("添加{0}到ThreadPool",item2);ThreadPool.QueueUserWorkItem(delegate{Load(item2,this.progCall,this.compCall);});线程数++;Thread.Sleep(100);//去掉这一行}Reference看代码立刻想到的一件事是没有使用Interlocked。你必须使用它,否则你会看到奇怪的错误和行为。而不是numThreads++;use:分享的所有内容,如果对你有用,需要进一步了解C#学习教程,希望大家多多关注—Interlocked.Increment(refnumThreads);本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: