C#多线程应用程序可以在每个线程中使用单独的WorkingDirectories吗?

时间:2013-06-13 22:32:43

标签: c# .net multithreading

在C#(.NET)中,在同一个应用程序中运行的两个线程可以有不同的“WorkingFolders”吗?

我能说的最好,答案是“不”。我认为WORKING DIR是由Win32中的PROCESS设置的。我错了吗?

根据以下测试代码(以及Win32 SetCurrentDirectory API调用),这是不可能的,但有没有人想出一种方法来实现它?

using System;
using System.Threading;

public class TestClass {

  public  ManualResetEvent _ThreadDone = new ManualResetEvent(false);

  public static void Main() {
    Console.WriteLine(Environment.CurrentDirectory);

    Thread _Thread = new Thread(new ParameterizedThreadStart(Go));
    TestClass test = new TestClass();

    _Thread.Start(test);
    if(test._ThreadDone.WaitOne()) {
      Console.WriteLine("Thread done.  Checking Working Dir...");
      Console.WriteLine(Environment.CurrentDirectory);
    }
  }

  public static void Go(object instance) {
    TestClass m_Test = instance as TestClass;
    Console.WriteLine(Environment.CurrentDirectory);
    System.IO.Directory.SetCurrentDirectory("L:\\Projects\\");
    Console.WriteLine(Environment.CurrentDirectory);
    m_Test._ThreadDone.Set();
  }
}

我知道有人在那之前必须遇到过这个问题!

2 个答案:

答案 0 :(得分:9)

我要猜测你尝试做的是让File.Open("Foo.txt")之类的代码在不同的线程上表现不同。你能做这个吗?简短的回答是 - 你也不应该尝试来做这件事。在Windows上,当前工作目录在进程级别设置。 .NET框架不违反该规则。

更好的方法是在Environment.CurrentDirectory之上创建一个特定于线程的抽象。类似的东西:

public static class ThreadEnvironment
{
   [ThreadStatic]
   static string _currentDir;

   public static string CurrentDirectory
   {
      get
      {
         if (_currentDir == null) // If Current Directory has not been set on this thread yet, set it to the process default
         {
            _currentDir = Environment.CurrentDirectory;
         }

         return _currentDir;
      }

      set
      {
         if (value == null)
            throw new ArgumentException("Cannot set Current Directory to null.");

         _currentDir = value;
      }
   }
}

然后,您可以引用ThreadEnvironment.CurrentDirectory来获取该线程的当前目录,如果尚未在该线程上设置,则该目录将默认为进程目录。例如:

static void Main(string[] args)
{
   (new Thread(Thread1)).Start();
   (new Thread(Thread2)).Start();
}

static void Thread1()
{
   Console.WriteLine("Thread1 Working Dir is: {0}", ThreadEnvironment.CurrentDirectory);
   ThreadEnvironment.CurrentDirectory = @"C:\";
   Console.WriteLine("Thread1 Working Dir is: {0}", ThreadEnvironment.CurrentDirectory);
}

static void Thread2()
{
   Console.WriteLine("Thread2 Working Dir is: {0}", ThreadEnvironment.CurrentDirectory);
   ThreadEnvironment.CurrentDirectory = @"C:\Windows";
   Console.WriteLine("Thread2 Working Dir is: {0}", ThreadEnvironment.CurrentDirectory);
}

当然,在处理文件IO时,您需要对该路径进行限定,但无论如何,这可以说是更安全的设计。

答案 1 :(得分:3)

  

有没有人想出办法让它成为可能?

只是不可能。每个App Domain甚至不能有不同的工作目录。

Windows规则是:每个进程设置一个环境。在.NET中运行不会改变基本规则。

除此之外,如果您在加载程序集时遇到问题,请考虑将相应的文件夹添加到PATH环境变量中。