在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();
}
}
我知道有人在那之前必须遇到过这个问题!
答案 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环境变量中。