Oggi voglio affrontare l' argomento delle chiamate Asyncrone. Prima una piccola e breve premessa.
Spesso ci capita di dover eseguire del codice ma senza bloccare l' applicazione che lo sta eseguendo. Allo stesso tempo vorremmo magari poter gestire e monitorare l' esecuzione di questo codice. Altre volte la necessità è quella di eseguire diverse operazioni simultaneamente, o magari, vorremmo che una volta eseguita un' operazione in BackGround, al suo termine vorremmo eseguirne un' altra. Insomma, spesso ci capita di voler lavorare in MiltiThreading. Oggi avro' il piacere di illustrarvi come usando C# e il NET Framework.
Per prima cosa dobbiamo creare un codice che possa essere eseguito in BackGround. Magari una bella query su un DataBase, o meglio ancora, un bel Loop ?
private int Search_Orders(out int threadId)
{
//Inizializzo il mio contatore
int value = 0;
//Prelevo il numero di thread
threadId = Thread.CurrentThread.ManagedThreadId;
//Eseguo la mia routine
Core.Mik_as400 conn = new Richiamo_Ordini.Core.Mik_as400();
value = conn.get_Table_Count("[nome_tabella]");
return value;
}
A questo punto, cosa ci serve? Un bel delegato che punti alla nostra funzione per poterla eseguire in modalità asyncrona, ovvero in un altro thread.
Se notate nella firma della mia funzione ho dovuto mettere un bel parametro in Ref per gestire il thread corrente nel quale verrà eseguita la mia funzione. Molto importante.
private delegate int Async_Search_Orders(out int threadId);
Arrivati a questo punto abbiamo una funzione che dobbiamo eseguire in modalità asyncrona e il suo delegato per richiamarla e poterne leggere il valore di ritorno. Non ci resta che associare per prima cosa il delegato alla funzione, chiaramente debbono avere la stessa firma ...
Async_Search_Orders asy =
new Async_Search_Orders(this.Search_Orders);
Ultima parte, dobbiamo usare l ' interfaccia IAsyncResult che detiene due metodi. Il primo BeginInvoke scatena questo meccanismo: la richiesta viene messa in coda dal CLR che ritorna subito al chiamante. A questo punto tramite il secondo metodo EndInvoke otteniamo il risultato del delegato, se ne vi è uno, altrimenti attendiamo il suo termine.
Async_Search_Orders asy =
new Async_Search_Orders(this.Search_Orders);
IAsyncResult result =
asy.BeginInvoke(out threadId, null, null);
count = asy.EndInvoke(out threadId, result);
In questo modo l' applicazione grafica non viene bloccata, ma comunque la sua esecuzione resta in attesa avendo chiamato endInvoke.