2013-08-26 10 views
7

Il seguente codice crea un nuovo thread che agisce prima come client di pipe denominato per l'invio di parametri e quindi come server per il recupero dei risultati. Dopodiché esegue una funzione in un altro AppDomain che funge da server named pipe e, successivamente, come client, per inviare nuovamente i risultati.C# Tutte le istanze di pipe sono occupate

public OrderPrice DoAction() 
{ 
    Task<OrderPrice> t = Task<OrderPrice>.Factory.StartNew(NamedPipeClient, parameters); 

    if (domain == null) 
    { 
    domain = AppDomain.CreateDomain(DOMAINNAME); 
    } 
    domain.DoCallBack(AppDomainCallback); 

    return t.Result; 
} 

static OrderPrice NamedPipeClient(object parameters) { 
    OrderPrice price = null; 

    using (NamedPipeClientStream stream = new NamedPipeClientStream(PIPE_TO)) { 
    stream.Connect(); 
    SerializeToStream(stream, parameters); 
    } 

    using (NamedPipeServerStream stream = new NamedPipeServerStream(PIPE_BACK)) { 
    stream.WaitForConnection(); 

    price = (OrderPrice)DeserializeFromStream(stream); 
    } 

    return price; 
} 

void AppDomainCallback() { 
    OrderPrice price = null; 

    using (NamedPipeServerStream stream = new NamedPipeServerStream(PIPE_TO)) { 
    stream.WaitForConnection(); 

    List<object> parameters = (List<object>)DeserializeFromStream(stream); 

    if (mi != null) 
     price = (OrderPrice)mi.Invoke(action, parameters.ToArray()); 
} 

    using (NamedPipeClientStream stream = new NamedPipeClientStream(PIPE_BACK)) { 
    stream.Connect(); 
    SerializeToStream(stream, price); 
    } 
} 

Il codice viene chiamato una volta al secondo in media e ha funzionato bene per 7+ ore. Ma ad un certo punto "system.io.ioexception tutte le istanze di pipe sono occupate" viene lanciata e non si ricollegheranno più dopo. Navigando qui sembra che potrebbe essere dovuto al fatto di non disporre correttamente gli oggetti pipe, ma immagino che tutto sia a posto visto che sono dentro usando le istruzioni. Qualcuno ha idea di cosa potrebbe esserci di sbagliato qui? Il codice è in .NET 4.0 in esecuzione su server Windows 2008.

+3

L'eccezione viene generata quando si tenta di accedere a una pipe da più thread contemporaneamente. I tubi non sono thread-safe, sei sicuro di non accedervi contemporaneamente con i due thread? – hcb

+0

durante la creazione di più thread che chiamano DoAction il codice si arresta in modo anomalo durante la prima chiamata perché viene creata una seconda istanza NamedPipeServerStream (PIPE_TO). Ho provato ad aggiungere il blocco (SyncToObject) ma il codice è stato inserito due volte ancora. Penso che funzioni in un AppDomain separato ma non sono sicuro di come utilizzare gli oggetti in Appdomains separati – Laurijssen

+0

È possibile spostare la chiamata in AppDomainCallback() nell'attività? O quel metodo viene chiamato automaticamente su un altro thread perché si trova in un altro dominio? – hcb

risposta