NLV*_*NLV -2 .net c# scope asynchronous
我在我的应用程序中有以下代码.
MyEventHandler handler = null; //Declare the handler
foreach (string pname in group)
{
handler = getHandler(pname); //Get the handler
if(handler == null)
{
throw new KeyNotFoundException("No user " + pname + " could be found");
}
//invoke the handler
handler.BeginInvoke(this, e, new AsyncCallback(EndAsync), null);
}
Run Code Online (Sandbox Code Playgroud)
所以我得到了处理程序和调用BeginInvoke方法.但是在BeginInvoke被调用之前它会进入下一次迭代并且处理程序值会发生变化.因此BeginInvoke,这个新的处理程序正在参与其中.
希望你明白我的观点.那我怎么能消除这个问题呢?BeginInvoke因为我觉得这是一个时间的流逝,我不想打电话给睡觉.
有任何想法吗?
Update1 我很确定在调用BeginInvoke()之前处理程序对象会被更改.我猜BeginInvoke需要一些时间来创建一个单独的线程来调用另一个函数.
UPDATE2 此代码位于WCF服务中,客户端调用一个函数,该函数依次使用此函数.我为每个客户端分别存储在我的服务器中的处理程序.WCF服务具有双工合同,为客户端分隔会话.我看到执行此函数后,同一个用户被调用两次.但我设置了一个断点并调试它(这给BeginInvoke提供了调用函数所需的时间)它"完美地"工作.我非常确定我在线程中也遇到了这个问题,我在循环中创建了多个线程.如果线程委托具有参数a,b,c,并且如果在下一次迭代开始时更改它,则会发生相同的行为.我之前有多少人遇到过这个问题.如果我放一个Sleep()或者如果我复制一个处理程序并使用copy调用它就可以了.
UPDATE3
好的,我现在已经测试过了.我刚刚添加了Thread.Sleep(),如下所示.
chatTo.BeginInvoke(this, e, new AsyncCallback(EndAsync), null);
Thread.Sleep(500);
Run Code Online (Sandbox Code Playgroud)
它的工作就像一个魅力.有什么想法吗?
更新4
我创建了一个演示问题的线程示例,我已将其上传到此处.我希望解决这个问题也能解决我的问题.请检查样品.
好的,在你的第四次编辑后,你提供了一个例子,它表明了一个问题,当然,但不是你要求帮助的问题.
你在问题中说的是:
您在发布的代码中展示的是:
这些都不是同样的问题!
你发布的代码行为不端的原因是所讨论的代码实际上看起来像这样:
int i;
for (i = 0; i < 10; i++)
... create delegate, capture i, spawn thread
Run Code Online (Sandbox Code Playgroud)
在这里,您将为所有线程捕获相同的变量.如果一个线程在循环更改变量之前没有开始执行,那么是的,您将看到该变量的"不正确的值".
但是,如果您更改这样的代码:
for (int i = 0; i < 10; i++)
{
int j = i;
ThreadStart threadStartObj = new ThreadStart(
delegate { PrintValueThreadFunction(j, j); });
^
|
+-- use j instead of i here
Run Code Online (Sandbox Code Playgroud)
然后,您将为每个线程捕获一个"新"变量,该变量不会被更改.
所以,问题仍然存在.这是你遇到的问题吗?如果是这样,那么下次羞辱你,不要简化问题.你在浪费人们的时间,尤其是你自己的时间.如果您在上面发布了类似上面的代码,那么您将在几分钟内得到一个答案(或一个重复的问题,指向现有的答案,有很多).
如果这不是您遇到的问题,那么您仍然遇到一个事件处理程序的问题,就像在不止一次调用的原始代码中一样,返回并生成一个更好的示例项目.
| 归档时间: |
|
| 查看次数: |
227 次 |
| 最近记录: |