2013-06-07 14 views
8

Nel nostro progetto .net facciamo riferimento a una DLL CLI di terze parti. Questa DLL è solo un'interfaccia alla loro libreria C++ proprietaria. Il nostro progetto è un'applicazione web asp.net (MVC4/Web API).Riferimento a una DLL instabile

La libreria non gestita C++ è piuttosto instabile. A volte si blocca con es. puntatori penzolanti Non abbiamo modo di risolverlo e l'utilizzo di questa libreria è un'esigenza di prima classe per i clienti.

Quando l'applicazione si arresta in modo anomalo, il pool di applicazioni in IIS non risponde più. Dobbiamo riavviarlo, e così facendo ci vogliono un paio di minuti (sì, così tanto!).

Vorremmo mantenere questa DLL instabile dall'arresto anomalo della nostra applicazione. Qual è il modo migliore per farlo? Possiamo mantenere la DLL CLI in un AppDomain separato? Come?

Grazie in anticipo.

+0

Che cosa hai osservato? Il processo si blocca dopo un certo numero di chiamate? Sospetti che la DLL instabile abbia perdite di memoria? – xpereta

+0

Le perdite di memoria non sono state un problema fino ad ora. Durante lo sviluppo, la DLL a volte blocca il server di sviluppo con una violazione di accesso alla memoria. A volte il server di sviluppo utilizza ~ 70% della CPU fino a quando non uccido il processo.Quando viene distribuito in IIS, i problemi di arresto anomalo e di CPU non stanno davvero accadendo così tanto, ma una volta ogni tanto il processo di IIS smette di rispondere e un riavvio di IIS richiede molto tempo. – Schiavini

+0

Hai provato ad aumentare il tasso di riciclaggio del processo IIS? – xpereta

risposta

2

Vorrei prima aumentare il tasso di recyling del processo IIS, forse il codice DLL non riesce dopo un certo numero di chiamate o dopo che il processo raggiunge una certa quantità di utilizzo della memoria.

si possono trovare informazioni sulla configurazione di IIS 7.0 opzioni di riciclaggio qui: http://technet.microsoft.com/en-us/library/cc753179(v=ws.10).aspx

Nel tuo caso vorrei riciclare il processo in un momento specifico, quando si sa che c'è meno carico sulla domanda. E dopo un certo numero di richieste (inferiori al valore predefinito) per provare e avere un processo "fresco" la maggior parte del tempo.

Il processo di riciclaggio è aggraziato nel senso che il vecchio processo non viene interrotto fino a quando quello che lo sostituirà non è pronto, quindi non ci dovrebbero essere tempi di fermo notevoli. Ulteriori informazioni sul meccanismo di riciclaggio qui: http://technet.microsoft.com/en-us/library/cc745955.aspx

Se quanto sopra non risolve il problema, avvolgo le chiamate nel mio codice che gestisce l'esecuzione della DLL instabile.

Questo codice deve essere ripristinato dagli errori, ad esempio ripetendo le chiamate in errore fino a quando non si ottiene un risultato e con un errore grazioso se non è possibile dopo un numero di tentativi.

Internamente le chiamate alla DLL instabile potrebbero essere eseguite in un thread generato o anche il codice potrebbe essere in un nuovo eseguibile esterno che è possibile avviare con Process.Start.

Quest'ultima opzione ha un sovraccarico, ma potrebbe essere l'unica opzione. Vedere questa domanda SO per ulteriori informazioni al riguardo: How do you handle a thread that has a hung call?

6

Penso che ogni risposta a questa domanda sarà una sorta di soluzione.

La mia soluzione alternativa sarebbe quella di non interagire direttamente con la DLL dalla propria applicazione web.

Scrivete invece le vostre richieste dall'applicazione web a una coda di messaggi oa una tabella SQL. È quindi possibile avere un'altra applicazione come un servizio di Windows che legge le richieste, interagisce con la DLL e quindi scrive i risultati per la lettura della tua applicazione web.

Non sto dicendo che SQL/Message Queues sono il modo giusto, sto pensando più al flusso generale del processo.

2

Suggerisco la seguente soluzione.

  1. Completa questa dll con un'altra applicazione web. Può essere uno dei seguenti. Dato che usi già la web api, è più adatto a te.

    1. semplice ASMX servizio Web
    2. servizio WCF
    3. Asp.Net MVC - WEB API Service
  2. Controlla il tuo p-richiamare il codice in modo che non si dispone di alcun bug? Vedi i seguenti articoli.

    1. The Black Art of P/Invoke and Marshaling in .NET
    2. P/Invoke Revisited
  3. Pubblica questa applicazione per IIS con diversa applicazione piscina.
  4. Utilizzare le tecniche standard suggerite prima del simile. Suggerisco di configurare il riciclo di IIS sia per la memoria che per i tempi programmati.
    1. IIS process recycling rate
    2. How to limit the memory used by an application in IIS?
+0

Non vedo come il wrapping con un'altra applicazione web possa aiutarmi. IIS sarebbe ancora bloccato. – Schiavini

+0

Ogni pool di applicazioni è un processo diverso. La tua applicazione principale in un pool diverso, questo processo diverso continua a funzionare. –

+0

Ma non può essere ripristinato da un arresto anomalo dall'altra applicazione poiché il processo sarà bloccato – Schiavini

4

Ho avuto questo problema esatto con una libreria di terze parti che accede memoria protetta per scopi di interagire con un dongle hardware di protezione dalla copia. Ha funzionato bene in una console o in un'app Winforms, ma si è bloccato come un matto quando chiamato da un'applicazione IIS.

Abbiamo provato diverse cose, alcune delle quali sono menzionate in altre risposte in questa pagina. Ma alla fine, la soluzione migliore per noi era per noi una tecnologia molto antica: .Net Remoting. Lo so - è un po 'aggrottato la fronte in questi giorni. Ma si adatta abbastanza bene a questo particolare bisogno.

Il codice instabile è stato inserito in un'applicazione di servizio Windows. L'applicazione Web ha effettuato chiamate remote a questo servizio, che ha inoltrato i comandi alla libreria di terze parti.

Ora sono sicuro che potreste fare la stessa cosa con WCF, prese, ecc. Ma il remoting era veloce e facile da configurare, e dal momento che parliamo solo con lo stesso server funziona senza aprire alcuna porta. Parla solo di una pipa con nome.

Significa un secondo servizio da installare oltre all'applicazione Web, ma che era accettabile nel mio particolare caso d'uso.

Se hai fatto qualcosa di simile, e il codice di terze parti ha effettivamente bloccato il servizio, probabilmente potresti scrivere del codice nell'applicazione principale per farlo eseguire il backup.

Quindi, forse un limite di processo è più utile di un dominio app quando si dispone di codice instabile per il wrangle.

Problemi correlati