开发者

thread in for loop!! unexpected behaviour?

I am creating thread in for loop, as per iteration one thread is get created. In this thread I am calling a method that take path from array of paths. When I run it debug mode step by step thread call the method with each path from the array of paths. but when I run it normally, the thread call the method with unexpected paths. Some time it take same paths 2 times and sometimes same path used all time.

What is the issue with code? I run the code without thread it runs perfectly but only in thread the problem goes.

Here is the code:

 for (int i = 0; i < appConfigDataPath.Length; i++)
 {
      var handle = new EventWaitHandle(false, EventResetMode.ManualReset);
      string serverPath = appConfig开发者_开发知识库DataPath[i];
      string serverName = appConfigDataName[i];

      var threadSplit = new Thread(() =>
                 {
                     ScanProcess(serverPath, serverName);
                     handle.Set();
                 });
      threadSplit.Start();
      waitHandles[i] = handle;
 }


You need to define distinct, local variables to hold your path information in each iteration of the loop. The problem is due to the nature of 'closures' when using Lambda expressions with external variables, as you are here.

If you declare serverPath and serverName locally, within the loop instead of externally, it should work as expected.


The problem is serverPath is changed before ScanProcess is actually called.

  1. serverPath=path0
  2. startThread0
  3. serverPath=path1
  4. thread0:ScanProcess(serverPath,..), serverPath is already path1
  5. startThread1
  6. thread1:ScanProcess(serverPath,..), serverPath is still path1

You need to pass the values in through the Start function as a copy. try this:

class Data
{
  public string Path;
  public string Name;
  public EventWaitHandle Handle;
  public Data (string path, string name, EventWaitHandle handle)
  {
     Path = path;
     Name = name;
     Handle = handle;
  }
}


var threadSplit = new Thread((obj) =>
{
  Data data = obj as Data;
  ScanProcess(data.Path, data.Name);
  data.Handle.Set();
});
threadSplit.Start(new Data(serverPath, serverName, handle));


Your serverPath and serverName are in the outer scope of your thread closure. You should make them local. Declaring them inside the loop scope will resolve this issue.


I'm not sure who is using the waitHandles array...but try moving the assignment.....

var threadSplit = new Thread(() =>
{
  ScanProcess(serverPath, serverName);
  handle.Set();
});
waitHandles[i] = handle;  // assign handle before starting thread.
threadSplit.Start();

Edit: And as others noticed (bleck...I missed them) serverPath, serverName and handle must be local.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜