Z logiki biznesowej obudowane za synchronicznego serwisu wymaga np .:Strategie wywołanie synchroniczne usługi wywołuje asynchronicznie w C#
interface IFooService
{
Foo GetFooById(int id);
int SaveFoo(Foo foo);
}
Jaki jest najlepszy sposób na rozszerzenie/korzystania z tych zgłoszeń serwisowych w asynchronicznego mody?
Obecnie Stworzyłem prostą klasę 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);
}
}
}
}
który pozwala mi nazwać coś asynchronicznie:
AsyncUtils(
() => _fooService.SaveFoo(foo),
id => HandleFooSavedSuccessfully(id),
ex => HandleFooSaveError(ex));
Chociaż to działa w prostych przypadkach używać go szybko staje się trudne, jeśli innych procesów Muszę skoordynować wyniki, na przykład, jeśli potrzebuję zapisać asynchronicznie trzy obiekty, zanim bieżący wątek będzie mógł kontynuować, chciałbym mieć sposób oczekiwania na dołączenie do wątków roboczych.
Opcje myślałem od tej pory to:
- o AsyncUtils zwrócić WaitHandle
- o AsyncUtils użyć AsyncMethodCaller i zwracają IAsyncResult
- przepisanie API obejmują Begin End połączeń async
np. coś podobnego:
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);
}
Czy są inne podejścia, które powinienem rozważyć? Jakie są zalety i potencjalne pułapki każdego z nich?
Idealnie chciałbym, aby warstwa usługi była prosta/synchroniczna i zapewniała kilka łatwych w użyciu metod narzędziowych do wywoływania ich asynchronicznie. Chciałbym usłyszeć o rozwiązaniach i pomysłach mających zastosowanie do C# 3.5 i C# 4 (nie zaktualizowaliśmy jeszcze, ale zrobimy to w najbliższej przyszłości).
Czekam na Twoje pomysły.
Dlaczego nie używasz biblioteki zadań? Został stworzony do tego. http://msdn.microsoft.com/en-us/library/dd460717.aspx –
Co John powiedział, ale w szczególności, spróbuj 'Lazy'. –
@Steven: To powinno być zadanie, dla tego typu operacji. Lazy służy do inicjowania. –