2012-10-19 12 views
5

Sto tentando di aprire un proxy su un thread (in background), il thread crea una nuova istanza del proxy, chiama un metodo del servizio e immediatamente dopo elimina il servizio.Avvio di più servizi sui thread

Tutto questo avviene su un thread:

var background = new Thread(() => 
{ 
    var proxy = new AssignmentSvcProxy(new EndpointAddress(worker.Address));    

    try 
    { 
     proxy.Channel.StartWork(workload); 
     proxy.Dispose();     
    } 
    catch (EndpointNotFoundException ex) 
    { 
     logService.Error(ex);       
     proxy.Dispose(); 
     proxy = null; 
    } 
    catch (CommunicationException ex) 
    { 
     logService.Error(ex); 
     proxy.Dispose(); 
     proxy = null; 
    } 
    catch (TimeoutException ex) 
    { 
     logService.Error(ex);      
     proxy.Dispose(); 
     proxy = null; 
    } 
    catch (Exception ex) 
    { 
     logService.Error(ex);      
     proxy.Dispose(); 
     proxy = null; 
    }     

}) { IsBackground = true }; 

background.Start(); 

Continuo a vedere problemi di timeout intermittenti che accadono anche se ho impostato il timeout al massimo per CloseTimeout, OpenTimeout, ReceiveTimeout, SendTimeout.

Voglio solo assicurarmi che il design non sia un problema, ad esempio aprire un servizio su un thread e smaltirlo?

EDIT:

Proxy stabilisce internamente un canale con rilegatura personalizzata su diversi punti finali per ciascun filo.

+0

E 'un po' di confusione che si parla di "servizio", dove mi aspetto "Proxy" (o anche "Cliente"), ad esempio, "il thread apre il servizio" dovrebbe essere "il thread apre un proxy per il mio servizio", giusto? – Jeroen

+0

Mi spiace, ho appena aggiornato la domanda, quindi in pratica il mio servizio è già aperto ma sì il proxy chiama semplicemente proxy.Channel.StartWork (carico di lavoro); di quel particolare servizio (che è già auto-ospitato) - ha senso? –

+0

potresti voler aggiungere un 'finally' alla tua clausola try-catch. infine esegue il codice anche se viene generata un'eccezione. Per quanto riguarda il tuo problema, sono incerto. Credo anche che sarebbe saggio passare la tua associazione nel costruttore. questa potrebbe essere la causa della tua eccezione di timeout. –

risposta

6

Penso che il problema potrebbe risiedere nel fatto che non si stanno chiudendo correttamente i proxy. Se ci sono molti thread che colpiscono il server e non si stanno ripulendo tutti da soli, è possibile che si verifichino dei timeout su tali connessioni.

Il dispose non è ideale per le connessioni di chiusura. Maggiori informazioni qui: Disposing proxies

Il modello ideale da utilizzare è la seguente:

try 
{ 
    proxy.Close(); 
} 
catch (Exception ex) 
{ 
    proxy.Abort(); 
} 
finally 
{ 
    proxy = null; 
} 

si tenta di chiudere la connessione, se non riesce, si interrompe tutte le connessioni. Smaltire non abortire se c'è un'eccezione.

Come tale, vorrei refactoring in questo modo:

var background = new Thread(() => 
{ 
    var proxy = new AssignmentSvcProxy(new EndpointAddress(worker.Address));    

    try 
    { 
     proxy.Channel.StartWork(workload); 
    } 
    catch (Exception ex) 
    { 
     // You aren't doing anything special with your specific exception types 
     logService.Error(ex);      
    }     
    finally 
    { 
     try 
     { 
      proxy.Close(); 
     } 
     catch (Exception ex) 
     { 
      proxy.Abort(); 
     } 
     finally 
     { 
      proxy = null; 
     } 
    } 

}) { IsBackground = true }; 

background.Start(); 
+1

Questo funziona. Tuttavia, i proxy WCF sono thread-safe (le chiamate simultanee sono serializzate). Poiché la creazione di un proxy e l'apertura di una nuova connessione al server sono operazioni costose, in genere i proxy vengono riutilizzati attraverso i thread. –

+0

Sono d'accordo, ed è per questo che dovrebbe idealmente avere un meccanismo di riprova nel caso in cui la connessione fallisca per qualsiasi motivo. Questo modello nella gestione degli errori assicurerebbe quindi che la vecchia connessione venga pulita prima di essere costretta a crearne una nuova. – Bardia

Problemi correlati