Con la logica di business incapsulato dietro sincrono servizio chiamate ad es .:Strategie per chiamare il servizio sincrono chiamate in modo asincrono in C#
interface IFooService
{
Foo GetFooById(int id);
int SaveFoo(Foo foo);
}
Qual è il modo migliore per estendere/utilizzare queste chiamate di servizio in un asincrono moda?
Attualmente ho creato una semplice classe AsyncUtils:
public static class AsyncUtils
{
public static void Execute<T>(Func<T> asyncFunc)
{
Execute(asyncFunc, null, null);
}
public static void Execute<T>(Func<T> asyncFunc, Action<T> successCallback)
{
Execute(asyncFunc, successCallback, null);
}
public static void Execute<T>(Func<T> asyncFunc, Action<T> successCallback, Action<Exception> failureCallback)
{
ThreadPool.UnsafeQueueUserWorkItem(state => ExecuteAndHandleError(asyncFunc, successCallback, failureCallback), null);
}
private static void ExecuteAndHandleError<T>(Func<T> asyncFunc, Action<T> successCallback, Action<Exception> failureCallback)
{
try
{
T result = asyncFunc();
if (successCallback != null)
{
successCallback(result);
}
}
catch (Exception e)
{
if (failureCallback != null)
{
failureCallback(e);
}
}
}
}
che mi permette di chiamare qualsiasi cosa in modo asincrono:
AsyncUtils(
() => _fooService.SaveFoo(foo),
id => HandleFooSavedSuccessfully(id),
ex => HandleFooSaveError(ex));
Mentre questo funziona in semplici casi di utilizzo diventa rapidamente difficile se altri processi è necessario coordinare i risultati, ad esempio se devo salvare tre oggetti in modo asincrono prima che il thread corrente possa continuare, quindi mi piacerebbe un modo per attendere/unire i thread worker.
Opzioni ho pensato finora includono:
- hanno AsyncUtils restituire un WaitHandle
- aventi AsyncUtils utilizzano un AsyncMethodCaller e restituiscono un IAsyncResult
- riscrivere l'API per includere Begin, terminare le chiamate asincrone
es. qualcosa di simile:
interface IFooService
{
Foo GetFooById(int id);
IAsyncResult BeginGetFooById(int id);
Foo EndGetFooById(IAsyncResult result);
int SaveFoo(Foo foo);
IAsyncResult BeginSaveFoo(Foo foo);
int EndSaveFoo(IAsyncResult result);
}
Ci sono altri approcci che dovrei prendere in considerazione? Quali sono i vantaggi e le potenziali insidie di ciascuno?
Idealmente mi piacerebbe mantenere il livello di servizio semplice/sincrono e fornire alcuni metodi di utilità facili da usare per chiamarli in modo asincrono. Sarei interessato a conoscere soluzioni e idee applicabili a C# 3.5 e C# 4 (non abbiamo ancora aggiornato, ma lo faremo nel prossimo futuro).
In attesa di vostre idee.
Perché non si utilizza la Libreria parallela attività? E 'stato fatto per questo. http://msdn.microsoft.com/en-us/library/dd460717.aspx –
Ciò che John ha detto, ma in particolare, prova "Lazy". –
@Steven: dovrebbe essere l'attività, per questo tipo di operazione. Lazy è per l'inizializzazione. –