C# 线程为循环!!意外行为?

C# 线程为循环!!意外行为?,c#,multithreading,C#,Multithreading,我正在for循环中创建线程,因为每次迭代都会创建一个线程。在这个线程中,我调用了一个从路径数组中获取路径的方法。当我运行调试模式时,线程会使用路径数组中的每个路径一步一步地调用该方法。但是,当我正常运行它时,线程使用意外路径调用该方法。有时,它会使用相同的路径2次,有时会一直使用相同的路径 代码有什么问题?我在没有线程的情况下运行代码,它运行得很好,但只有在线程中问题才会出现 代码如下: for (int i = 0; i < appConfigDataPath.Length; i++)

我正在for循环中创建线程,因为每次迭代都会创建一个线程。在这个线程中,我调用了一个从路径数组中获取路径的方法。当我运行调试模式时,线程会使用路径数组中的每个路径一步一步地调用该方法。但是,当我正常运行它时,线程使用意外路径调用该方法。有时,它会使用相同的路径2次,有时会一直使用相同的路径

代码有什么问题?我在没有线程的情况下运行代码,它运行得很好,但只有在线程中问题才会出现

代码如下:

 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

  • 服务器路径=路径0
  • 开始线程0
  • 服务器路径=路径1
  • thread0:ScanProcess(服务器路径,…),服务器路径已经是路径1
  • 开始线程1
  • thread1:ScanProcess(服务器路径,…),服务器路径仍然是路径1
  • 您需要通过Start函数将值作为副本传入。 试试这个:

    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

  • 服务器路径=路径0
  • 开始线程0
  • 服务器路径=路径1
  • thread0:ScanProcess(服务器路径,…),服务器路径已经是路径1
  • 开始线程1
  • thread1:ScanProcess(服务器路径,…),服务器路径仍然是路径1
  • 您需要通过Start函数将值作为副本传入。 试试这个:

    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
    的实现。