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.
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
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
È 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