Value getting changed in the iteration before the call begins

南笙酒味 提交于 2019-11-27 16:32:15

I can't see why this would happen - the code you posted cannot possibly reproduce the behaviour you describe. It's entirely reasonable that the BeginInvoke call might not actual do anything straight away, and that the next iteration might occur before you actually see that call do anything - since it will be queued for processing by a worker thread.

This doesn't mean that a different handler is being invoked - the handler to be invoked is captured as soon as BeginInvoke is called, so it won't matter if the local variable changes afterwards.

Also - why have you got the lock here? Unless multiple threads are doing this processing at the same time over the same enumerable (in which case why would you do that) I can't see any reason why you would lock.

I would also say that if you're judging this behaviour by what you see in the debugger, then you shouldn't worry - you'll get 'interesting' results from the debugger by doing this, and with the multiple threads in the mix it's important to switch threads in the 'Threads' debugger window.

The question is - does your program actually do what you expect? If so, but you're seeing this strange behaviour whilst debugging - then that's entirely normal.

As a few comments have stated - the code you posted can't be exactly what's producing the problem. If, for example, 'handler' is a local variable shared between multiple threads that then perform this iteration then, yes, you could get something like this. But a variable local to a method can only be modified (and indeed read) by the same thread that's currently in that method; the only exception to that rule being if the handler reference is then passed out to another threaded method as a ref.

Ok, after your fourth edit you provide us with an example, that exhibits a problem, sure, but not the problem you're asking for help about.

What you're saying in the question is that:

  • I use BeginInvoke on a delegate variable, then change the variable, and somehow my delegates are invoked twice

What you exhibit in the posted code is that:

  • I capture a loop variable in an anonymous method, and somehow I use the wrong variable value

THESE ARE NOT THE SAME PROBLEM!

The reason for your posted code misbehaving is that the code in question actually looks like this under the hood:

int i;
for (i = 0; i < 10; i++)
    ... create delegate, capture i, spawn thread

Here you're capturing the same variable for all the threads. If a thread doesn't start executing before the loop changes the variable, then yes, you will see the "incorrect value" for that variable.

However, if you change the code like this:

for (int i = 0; i < 10; i++)
{
    int j = i;
    ThreadStart threadStartObj = new ThreadStart(
        delegate { PrintValueThreadFunction(j, j); });
                                            ^
                                            |
                                            +-- use j instead of i here

Then you will capture a "fresh" variable for each thread, which won't get changed.

So, the question remains. Is this the problem you're having? If so, then shame on you, next time, don't simplify the problem. You're wasting people's time, most of all your own. Had you posted code like the above to begin with you would've had an answer (or a duplicate question pointing to existing answers, there's plenty) within a couple of minutes.

If this is not the problem you're having, you're still having problem with an event handler like in the original code being invoked more than once, go back and produce a better example project.

I think you're having some other problem... handler.BeginInvoke can't be called after next iteration, you're still in the same thread...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!