C# 线程为循环!!意外行为?
我正在for循环中创建线程,因为每次迭代都会创建一个线程。在这个线程中,我调用了一个从路径数组中获取路径的方法。当我运行调试模式时,线程会使用路径数组中的每个路径一步一步地调用该方法。但是,当我正常运行它时,线程使用意外路径调用该方法。有时,它会使用相同的路径2次,有时会一直使用相同的路径 代码有什么问题?我在没有线程的情况下运行代码,它运行得很好,但只有在线程中问题才会出现 代码如下:C# 线程为循环!!意外行为?,c#,multithreading,C#,Multithreading,我正在for循环中创建线程,因为每次迭代都会创建一个线程。在这个线程中,我调用了一个从路径数组中获取路径的方法。当我运行调试模式时,线程会使用路径数组中的每个路径一步一步地调用该方法。但是,当我正常运行它时,线程使用意外路径调用该方法。有时,它会使用相同的路径2次,有时会一直使用相同的路径 代码有什么问题?我在没有线程的情况下运行代码,它运行得很好,但只有在线程中问题才会出现 代码如下: for (int i = 0; i < appConfigDataPath.Length; i++)
for (int i = 0; i < appConfigDataPath.Length; i++)
{
var handle = new EventWaitHandle(false, EventResetMode.ManualReset);
string serverPath = appConfigDataPath[i];
string serverName = appConfigDataName[i];
var threadSplit = new Thread(() =>
{
ScanProcess(serverPath, serverName);
handle.Set();
});
threadSplit.Start();
waitHandles[i] = handle;
}
for(int i=0;i
{
扫描进程(服务器路径、服务器名称);
handle.Set();
});
threadSplit.Start();
waitHandles[i]=句柄;
}
您需要定义不同的局部变量,以便在循环的每次迭代中保存路径信息。这个问题是由于使用带有外部变量的Lambda表达式时“闭包”的性质造成的,就像您在这里看到的那样
如果在循环内部而不是外部本地声明
serverPath
和serverName
,则它应该按预期工作。您需要定义不同的本地变量,以便在循环的每次迭代中保存路径信息。这个问题是由于使用带有外部变量的Lambda表达式时“闭包”的性质造成的,就像您在这里看到的那样
如果在循环内部而不是外部本地声明
serverPath
和serverName
,则它应该按预期工作。您的serverPath和serverName在线程闭包的外部范围内。你应该让他们成为本地人。在循环范围内声明它们将解决此问题。您的serverPath和serverName位于线程闭包的外部范围内。你应该让他们成为本地人。在循环范围内声明它们将解决此问题。我不确定谁在使用waitHandles数组…但请尝试移动分配
var threadSplit = new Thread(() =>
{
ScanProcess(serverPath, serverName);
handle.Set();
});
waitHandles[i] = handle; // assign handle before starting thread.
threadSplit.Start();
编辑:正如其他人所注意到的(bleck…我错过了他们)serverPath、serverName和handle必须是本地的。我不确定谁在使用waitHandles数组…但请尝试移动分配
var threadSplit = new Thread(() =>
{
ScanProcess(serverPath, serverName);
handle.Set();
});
waitHandles[i] = handle; // assign handle before starting thread.
threadSplit.Start();
编辑:正如其他人所注意到的(bleck…我错过了他们)serverPath、serverName和handle必须是本地的。问题是在实际调用ScanProcess之前更改了serverPath
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));
问题是在实际调用ScanProcess之前更改了serverPath
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));
您应该将IsBackgroundThread属性设置为true。更重要的是,使用线程池中的线程或使用并行任务来获得更好的性能。这才是问题所在。我重新限制为…使用线程池或并行。。。。我必须用普通的线程来做
ScanProcess
做什么?它使用数组吗?您是否尝试过在循环中使用一个不同的值int变量,int x=i;然后使用变量x?应该将IsBackgroundThread属性设置为true。更重要的是,使用线程池中的线程或使用并行任务来获得更好的性能。这才是问题所在。我重新限制为…使用线程池或并行。。。。我必须用普通的线程来做ScanProcess
做什么?它使用数组吗?您是否尝试过在循环中使用一个不同的值int变量,int x=i;然后使用变量x?+1,但OP编辑了他的问题,以显示本地声明的变量。但是原始的代码可能就是他正在运行的。@Josh Einstein-在我看来,他可能是为了尝试而编辑代码的,但它不起作用。至少,礼貌一点,这就是我要说的!我想我们需要看看impl。但是OP编辑了他的问题,以显示那些在本地声明的变量。但是原始的代码可能就是他正在运行的。@Josh Einstein-在我看来,他可能是为了尝试而编辑代码的,但它不起作用。至少,礼貌一点,这就是我要说的!我想我们需要看看impl。但这种方法很奇怪。您是否尝试放置threadSplit.Start()代码>在循环的末尾?如果它也不起作用,那么您应该向我们展示ScanProcess
@GAPS:wird的实现。您是否尝试放置threadSplit.Start()代码>在循环的末尾?如果它也不起作用,您应该向我们展示ScanProcess
的实现。