Ho appena "guadagnato" il privilegio di mantenere una libreria legacy codificata in C# nel mio lavoro corrente.Rendi il mio assembly assembly COM asincrono
questa DLL:
- espone i metodi per un grande sistema legacy realizzato con Uniface, che non ha altra scelta che chiamare oggetti COM.
- funge da collegamento tra questo sistema legacy e un'altra API di sistema.
- Utilizza WinForm per l'interfaccia utente in alcuni casi.
più visivamente, mi pare di capire i componenti:
*[Big legacy system in Uniface]*
== [COM] ==>[C# Library]
== [API Managed] ==>*[Big EDM Management System]*
La domanda è: : Uno dei metodi in questa libreria C# richiede troppo tempo per essere eseguito e I "dovrebbe" renderlo asincrono!
Sono abituato a C#, ma non a COM affatto. Ho già fatto la programmazione concorrente, ma COM sembra aggiungere un sacco di complessità ad esso e tutte le mie prove finora finire in uno:
- Un incidente senza alcun messaggio di errore affatto
- mio Dll solo parzialmente funzionante (visualizzando solo parte della sua interfaccia utente e quindi chiudendo), e ancora non mi ha dato alcun errore
Sono a corto di idee e risorse su come gestire i thread all'interno di una DLL COM, e vorrei apprezzare qualsiasi suggerimento o aiuto.
Finora, la maggior parte del codice ho cambiato a fare il mio metodo asincrono:
// my public method called by the external system
public int ComparedSearch(string application, out string errMsg) {
errMsg = "";
try {
Action<string> asyncOp = AsyncComparedSearch;
asyncOp.BeginInvoke(application, null, null);
} catch (ex) {
// ...
}
return 0;
}
private int AsyncComparedSearch(string application) {
// my actual method doing the work, that was the called method before
}
Qualsiasi suggerimento o una risorsa utile sarebbe apprezzato. Grazie.
UPDATE 1:
Di seguito le risposte e gli indizi sottostanti (in particolare circa la SynchronizationContext
, e con l'aiuto di this example) sono stato in grado di refactoring il mio codice e renderlo al lavoro, ma solo quando chiamato da un altro Applicazione finestra in C# e non tramite COM. Il sistema legacy incontra un errore piuttosto oscuro quando chiamo la funzione e non fornisco dettagli sull'arresto.
UPDATE 2:
Ultimi aggiornamenti nelle mie prove: sono riuscito a far funzionare il multithreading quando le chiamate vengono effettuate da un progetto di test, e non dal sistema Uniface. Dopo diversi tentativi, tendiamo a pensare che il nostro sistema legacy non supporti bene il multithreading nella sua attuale configurazione.Ma non è questo il punto della questione più :)
Questo vuole essere un exerpt del codice che sembra funzionare:
string application;
SynchronizationContext context;
// my public method called by the external system
public int ComparedSearch(string application, out string errMsg) {
this.application = application;
context = WindowsFormsSynchronizationContext.Current;
Thread t = new Thread(new ThreadStart(AsyncComparedSearchAndShowDocs));
t.Start();
errMsg = "";
return 0;
}
private void AsyncComparedSearch() {
// ANY WORK THAT AS NOTHING TO DO WITH UI
context.Send(new SendOrPostCallback(
delegate(object state)
{
// METHODS THAT MANAGE UI SOMEHOW
}
), null);
}
Ora stiamo valutando altre soluzioni che modificare questa assemblea COM, come incapsulare questo libreria in un servizio di Windows e creazione di un'interfaccia tra il sistema e il servizio. Dovrebbe essere più sostenibile ..
+1 per questa domanda ben organizzata. – 3yanlis1bos
Puoi fornire un campione veramente piccolo che si bloccherà? Non sono sicuro di cosa stai facendo esattamente per farlo andare in crash :) (Se è colpa tua, o se è il sistema legacy che non può gestire il threading) – Onkelborg
Stai dicendo che l'eccezione non viene mai catturata o che non lo fa? non contiene alcun messaggio? –