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.
- serverPath=path0
- startThread0
- serverPath=path1
- thread0:ScanProcess(serverPath,..), serverPath is already path1
- startThread1
- 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.
精彩评论