Domanda

Ho un'app con la seguente architettura di base:

Un servizio Windows (servizio) che registra un tipo .NET (RemoteObject) per l'accesso remoto (.NET Remoting). RemoteObject crea thread non ThreadPool che utilizzano ThreadPool per eseguire l'elaborazione IO. La dimensione del ThreadPool deve essere limitata a un limite per un motivo particolare. Un'app GUI utilizza .NET Remoting per accedere a RemoteObject.

Ho notato che se la dimensione di ThreadPool è troppo bassa, l'app GUI si bloccherà quando si effettua una chiamata a RemoteObject.

La mia domanda è: come posso capire perché questo è sospeso e perché il thread RemoteObject dovrebbe essere influenzato da ThreadPool?

Questo mi sta facendo impazzire; grazie per il tuo aiuto!

È stato utile?

Soluzione 2

Si scopre che l'infrastruttura remota di .NET utilizza .NET ThreadPool (o condivide la risorsa sottostante), quindi le chiamate remote possono bloccarsi se tutti i thread ThreadPool sono in uso dalla tua app.

Altri suggerimenti

Non sono sicuro che questo possa aiutare (non so se questo è il tuo problema o no), ma se vuoi eseguire il debug del tuo servizio mentre è in esecuzione, puoi schiaffeggiarlo nel tuo codice:

#if DEBUG
            if (!System.Diagnostics.Debugger.IsAttached)
                Debugger.Launch();
#endif

e otterrai una finestra di dialogo che ti chiede di selezionare un debugger. È un modo semplice per collegarsi a un'istanza in esecuzione di un servizio. Se non altro, questo ti consentirà di interrompere il servizio quando l'interfaccia utente è sospesa (premendo il pulsante Pausa sulla barra degli strumenti di debug) e controlla i thread e il callstack.

Questo potrebbe non essere eccezionalmente utile, ma lo lancerò comunque là fuori.

Quando eseguo il debug di servizi e client che parlano tramite remoting, di solito eseguirò sempre due istanze del debugger: una per il client e una per il servizio. Giusto per essere chiari, sto eseguendo due copie di Visual Studio. Per il servizio puoi usare il comando attach oppure puoi modificare il main e chiamare direttamente start (ignorando tutto il codice del servizio).

Ecco come in genere abilito il debug modificando il main, dovrete e la chiamata DebugService al servizio, in realtà è solo un punto di ingresso che le chiamate iniziano. Una volta ottenuto questo, abilito solo il debug del servizio definendo SERVICE_DEBUG o modificando il #if aggiungendo un '!' . Ora hai praticamente convertito il tuo servizio in un'app console.

#if SERVICE_DEBUG
            ServiceHost s = new ServiceHost();
            s.DebugService();
            Thread.Sleep( 300000000 );

#else
            ServiceBase.Run( ServicesToRun );
#endif

Una volta che hai sia impostato che in esecuzione puoi passare attraverso il client, quando le chiamate remote hanno colpito il servizio puoi scorrere il codice del servizio, permettendoti di eseguire il debug di entrambi contemporaneamente.

Per curiosità stai chiamando l'oggetto remoto direttamente dal thread della GUI? In tal caso, il thread della GUI si bloccherà fino al completamento della chiamata remota. Ciò bloccherà l'intera GUI e la non risponderà. Questa non è la soluzione al problema, ma se è il caso e il thread del servizio non viene restituito, anche la GUI si bloccherà.

Alcuni anni fa, ho progettato e implementato un sistema aziendale critico che utilizzava .NET Remoting. Avevamo implementato un client come una GUI di Windows Form, un server implementato come un servizio Windows e un database SQL Server.

Ho progettato per la risoluzione dei problemi / debug / sviluppo, quindi uno dei miei primi criteri di progettazione era che potevo rimuovere banalmente l'intera implementazione di .NET Remoting ed eseguire l'intero sistema sul mio desktop. Quindi, ho potuto disattivare il remoting modificando una singola impostazione di configurazione booleana su "false" = spento. Potrei quindi risolvere i problemi, eseguire il debug, sviluppare completamente senza l'overhead o l'interferenza di .NET Remoting.

Sembra che questo sarebbe utile anche per la tua situazione. È un dato di fatto, non riesco a immaginare una situazione in cui questa non sia una caratteristica desiderabile, soprattutto perché è facile da implementare.

Quindi, per implementarlo, l'impostazione di configurazione è stata utilizzata da ciascuno dei client e dal codice del server per decidere quale classe di implementazione istanziare per la comunicazione con l'altro lato. Tutte le comunicazioni sono avvenute attraverso un'interfaccia C # personalizzata che aveva due classi di implementazione concrete su ciascun lato: una classe ha implementato la comunicazione utilizzando .NET Remoting, l'altra classe ha implementato la comunicazione come passthrough in-process diretto (chiamate dirette).

Solo una coppia di classi (una su ciascun lato) sapeva qualcosa su .NET Remoting, quindi l'isolamento era totale. Il più delle volte, tutti gli sviluppatori hanno lavorato con il telecomando disattivato, che era più veloce e più semplice. Quando ne avevano bisogno, in rare occasioni, l'hanno acceso (principalmente io o quando qualcuno si è collegato al test / produzione per la risoluzione dei problemi).

A proposito, ho reso l'interfaccia remota remota semplice:     esecuzione di risposta pubblica (richiesta)

Oltre a ciò, ho anche usato il suggerimento di lancio del debugger menzionato sopra e sono d'accordo che devi essere consapevole dell'impatto del threading della GUI.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top