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

Avaluechangesinaniterationbeforethecallstarts分享

时间:2023-04-10 19:40:16 C#

Avaluechangesinaniterationbeforethecallstarts我的应用程序中有以下代码。我的事件处理程序处理程序=null;//声明处理程序foreach(stringpnameingroup){handler=getHandler(pname);//获取处理器if(handler==null){thrownewKeyNotFoundException("Nouser"+pname+"couldbefound");}//调用处理程序handler.BeginInvoke(this,e,newAsyncCallback(EndAsync),null);所以我得到了处理程序并调用了BeginInvoke方法。但在调用BeginInvoke之前,它会进入下一次迭代并且处理程序值会更改。所以BeginInvoke涉及这个新的处理程序。希望你明白我的意思。那么我怎样才能消除这个问题呢?我不想在BeginInvoke之后调用睡眠,因为我觉得这是在浪费时间。有任何想法吗?Update1我很确定在调用BeginInvoke()之前更改了处理程序对象。我想BeginInvoke需要一些时间来创建一个单独的线程来调用另一个函数。Update2此代码位于WCF服务中,客户端调用一个函数,该函数又使用此函数。我为每个客户端分别将处理程序存储在我的服务器中。WCF服务具有双工合同,可以为客户端分隔会话。我看到执行此功能后,同一个用户被调用了两次。但是我放置了一个断点并对其进行了调试(这为BeginInvoke提供了调用该函数的必要时间)并且它“完美”地工作。我很确定线程也有这个问题,我在一个循环中创建多个线程。如果线程委托具有参数a、b、c,并且在下一次迭代开始时更改,则会发生相同的行为。在我之前有多少人遇到过这个问题。如果我放置一个Sleep()或者如果我复制一个处理程序并使用副本调用它,它就会工作。UPDATE3好的,我已经测试过了。我刚刚添加了Thread.Sleep(),如下所示。chatTo.BeginInvoke(this,e,newAsyncCallback(EndAsync),null);线程.睡眠(500);它就像一个魅力。有任何想法吗?更新4我创建了一个演示问题的示例线程,我已将其上传到此处。我希望解决这个问题也能解决我的问题。请检查样品。我不明白为什么会发生这种情况-您发布的代码不会重现您描述的行为。BeginInvoke调用可能不会立即执行任何操作,并且下一次迭代可能会在您实际看到该调用执行任何操作之前发生——因为它将排队等待工作线程处理,这是完全合理的。这并不意味着调用了不同的处理程序——一旦调用了BeginInvoke,就会捕获要调用的处理程序,因此后续局部变量是否发生变化并不重要。还有——你为什么锁在这里?除非多个线程在同一个可枚举对象上同时执行此处理(在这种情况下你为什么要这样做),否则我看不出你想要锁定的任何原因。我还要说的是,如果您根据在调试器中看到的内容来判断此行为,那么您不必担心-调试器将通过执行此操作获得“有趣”的结果,并且混入多个线程'在线程的调试器窗口中切换线程很重要。问题是——你的计划真的符合你的期望吗?如果是这样,但您在调试时看到了这种奇怪的行为——这是完全正常的。正如一些评论所说-您发布的代码不可能是问题的确切原因。例如,如果'handler'是一个在多个线程之间共享的局部变量,然后执行此迭代,那么,是的,你可以得到这样的东西。但是方法局部变量只能由当前在该方法中的同一个线程修改(实际读取);此规则的唯一例外是处理程序引用随后作为引用传递给另一个线程的方法。好的,在您的第4次编辑之后,您向我们提供了一个显示问题的示例,当然,但不是您寻求帮助的那个。您在问题中所说的:您在发布的代码中显示的内容:这些不是同一个问题!您发布的代码行为不当的原因是有问题的代码实际上看起来像这样:inti;for(i=0;i在这里,您为所有线程捕获相同的变量。如果一个线程更改循环中的变量之前没有开始执行,那么是的,您将看到该变量的“不正确的值”。但是,如果您按如下方式更改代码:for(inti=0;i那么,您将捕获一个“新”变量,该变量不会更改。因此,问题仍然存在。这是您遇到的问题吗?如果是这样,下次你会感到羞耻,不要简化事情。你在浪费别人的时间,尤其是你自己的时间。如果你开始发布上面的代码,你会在几分钟内得到答案(或者重复的问题指向一个现有的答案,有很多)。如果这不是你遇到的问题,你仍然是一个事件处理程序问题,就像在不止一次调用的原始代码中一样,返回并生成一个更好的例子project.我觉得你还有其他问题...handler.BeginInvoke不能在下一次迭代后调用,你还在同一个线程...以上是C#学习教程:迭代中的值会在调用前改变首发注意---本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: