Riduzione del tempo di blocco (applicazione multithread)

3

Ho un'applicazione web scritta in C # che usa una dll esterna scritta in C ++. La comunicazione tra client (browser Web) e un'applicazione Web avviene tramite SignalR. Per la comunicazione tra l'applicazione web e la DLL sto usando una classe e creo un'istanza di questa classe per ogni client connesso. L'istanza di questa classe è memorizzata nell'elenco statico, è condivisa tra le richieste.

Quando viene emessa una richiesta, prelevo un connettore (classe per comunicare con dll) da un elenco e poi richiama un metodo che può richiedere qualsiasi tempo tra 0,1 secondi e 3 secondi.

Inoltre ho un lavoro che viene attivato ogni minuto (usando Hangfire) che scorre attraverso l'elenco e dispone di connettori che sono inattivi per un certo periodo di tempo. Il connettore di smaltimento può anche richiedere circa 1 o 2 secondi.

Poiché l'applicazione è multithread, sto utilizzando un blocco condiviso tra la classe del connettore e il lavoro che dispone del connettore. Usando il blocco evito che il connettore sia disposto tra il recupero del connettore e la chiamata del metodo.

In "pseudo-codice" questo apparirebbe come:

object globalLock = new object();


-- signalr hub method
public void HubMethod(string sessionId, string param) {
  lock (globalLock) {
    DllConnector connector = GetConnector(sessionId);
    connector.CallMethod(param);
  }
}


-- hangfire job
public void KillInactive() {
  lock (globalLock) {
    foreach (DllConnector connector in listOfConnectors) {
      if (connector.IsInactive()) {
         listOfConnectors.Remove(connector);
         connector.Dispose();
      }
    }
  }
}

Domanda:

Poiché mi aspetto un numero "elevato" di client concorrenti (richieste), temo che ciò non si riduca - le richieste e il lavoro non risponderanno. Come posso evitare questo - minimizzare l'attesa per il blocco e per evitare i connettori disposti tra il recupero e la chiamata del metodo. Ci sono dei modelli?

    
posta rrejc 28.11.2015 - 21:53
fonte

1 risposta

1

Il modo in cui queste cose sono normalmente fatte è con i threadpool. Vedere System.Threading.ThreadPool e leggere MSDN: Procedura: utilizzare un pool di thread

Inoltre, l'approccio moderno alla condivisione dei dati negli ambienti con multithreading consiste nell'evitare di utilizzare i lock e di utilizzare invece il passaggio dei messaggi. Ciò si traduce in sistemi testabili e che, una volta che si sa che funzionano, tendono a continuare a funzionare senza brutte sorprese a causa di rari problemi di temporizzazione.

Nota: invocare listOfConnectors.Remove( x ); in foreach( var x in listOfConnectors ) genererà un'eccezione 'raccolta è stata modificata'.

    
risposta data 29.11.2015 - 02:32
fonte

Leggi altre domande sui tag