2013-06-13 11 views
11

In C# (.NET), due thread in esecuzione nella stessa applicazione hanno DIVERSI "WorkingFolders" ??Un'applicazione multithreaded C# può utilizzare le WorkingDirectories seprate per thread?

Come meglio posso dire, la risposta sarebbe "NO". Penso che il DIR di LAVORO sia impostato dal PROCESSO in Win32. Ho sbagliato qui?

In base al seguente codice di test, (come pure la chiamata API Win32 SetCurrentDirectory), questo NON è possibile, ma qualcuno ha escogitato un modo per renderlo possibile?

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(); 
    } 
} 

So che QUALCUNO là fuori deve essersi imbattuto in questo prima!

+5

Qual è il tuo obiettivo nel tentare questo? In genere è preferibile semplicemente progettare il codice per consentire di passare in cartelle appropriate ... –

+0

Probabilmente creando un dominio app separato per thread. Ho aggiunto questo come commento perché attualmente non riesco a mostrare un esempio. – MarcF

+1

@MarcF App Domains non modificherà l'unico set di impostazioni per processo (FYI). –

risposta

9

Ho intenzione di indovinare cosa sei provare provare a fare codice come File.Open("Foo.txt") comportarsi in modo diverso su thread diversi. Puoi farlo? La risposta breve è No - né si dovrebbe essere provare per fare questo. Su Windows, la directory di lavoro corrente è impostata a livello di processo. Il framework .NET non viola questa regola.

Un approccio migliore sarebbe creare un'astrazione su Environment.CurrentDirectory specifica per il thread. Qualcosa di simile:

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; 
     } 
    } 
} 

È quindi possibile fare riferimento a ThreadEnvironment.CurrentDirectory per ottenere directory corrente di quel filo, che di default nella directory di processo, se non è stato impostato su quel thread. Per esempio:

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); 
} 

Si potrebbe, ovviamente, poi bisogno di qualificare quel percorso ogni volta che si tratta di file di IO, tuttavia questo è senza dubbio un design più sicuro in ogni caso.

+0

Che ne pensi di creare diversi 'AppDomain's e impostare' AppDomainSetup.PrivateBinPath' lì? In questo modo può in qualche modo "impostarlo". Forse mi sbaglio – Odys

+1

Penso che l'obiettivo qui fosse quello di rendere 'File.Open (" Foo.txt ")' si comporta diversamente su thread differenti. E la risposta è no, non puoi farlo e non dovresti provare a farlo. –

3

qualcuno ha escogitato un modo per renderlo possibile?

È semplicemente non possibile. Non puoi nemmeno avere diverse directory di lavoro per dominio app.

La regola di Windows è: un ambiente impostato per processo. L'esecuzione in .NET non cambierà le regole di base.

Anziché, se si è verificato un problema nel caricamento degli assiemi, considerare l'aggiunta della cartella corrispondente alla variabile di ambiente PATH.

+0

Grazie Erik, questo è quello di cui sospettavo, ma credo che fino ad ora, Mike Christensen abbia la migliore risposta ... Questo mi consente di eseguire l'hardcode di CurrentDir + Passed Path/File alle mie funzioni IO e consentire l'attività I sto cercando. Ma, a causa della documentazione Win32, temevo che fosse il caso ... – LarryF

Problemi correlati