Skip to content

Instantly share code, notes, and snippets.

@jzi96
Created April 28, 2015 13:41
Show Gist options
  • Save jzi96/a11f53bca97d0e77f749 to your computer and use it in GitHub Desktop.
Save jzi96/a11f53bca97d0e77f749 to your computer and use it in GitHub Desktop.
This is a helper class to convert Begin-/End- Async pattern method to Tasks and use feature of the new .NET FX functions
public static class AsyncTaskConverter
{
public static Task FromAsync<TParameter>(Func<TParameter, AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod, TParameter parameter, object state)
{
if (beginMethod == null)
throw new ArgumentNullException("beginMethod");
if (endMethod == null)
throw new ArgumentNullException("endMethod");
var tcs = new TaskCompletionSource<bool>();
try
{
beginMethod(parameter, (iar) =>
{
try
{
endMethod(iar);
tcs.TrySetResult(true);
}
catch (OperationCanceledException ex)
{
tcs.TrySetCanceled();
tcs.TrySetResult(false);
}
catch (Exception ex)
{
tcs.TrySetException(ex);
tcs.TrySetResult(false);
}
}, state);
}
catch
{
tcs.TrySetResult(false);
throw;
}
return tcs.Task;
}
public static Task<TResult> FromAsync<TResult>(Func<AsyncCallback, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod, IList<Type> skipExceptions = null)
{
if (beginMethod == null)
throw new ArgumentNullException("beginMethod");
if (endMethod == null)
throw new ArgumentNullException("endMethod");
var tcs = new TaskCompletionSource<TResult>();
try
{
beginMethod((iar) =>
{
try
{
var result = endMethod(iar);
tcs.TrySetResult(result);
}
catch (OperationCanceledException ex)
{
tcs.TrySetCanceled();
}
catch (Exception ex)
{
if (skipExceptions == null || skipExceptions.Count == 0)
tcs.TrySetException(ex);
else
{
Type exType = ex.GetType();
for (int i = 0; i < skipExceptions.Count; i++)
{
if (skipExceptions[i].IsAssignableFrom(exType))
{
tcs.TrySetResult(default(TResult));
break;
}
}
}
}
});
}
catch
{
tcs.TrySetResult(default(TResult));
throw;
}
return tcs.Task;
}
public static Task<TResult> FromAsync<P1, TResult>(Func<P1, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod, P1 arg, object state, IList<Type> skipExceptions = null)
{
if (beginMethod == null)
throw new ArgumentNullException("beginMethod");
if (endMethod == null)
throw new ArgumentNullException("endMethod");
var tcs = new TaskCompletionSource<TResult>();
try
{
//Bis auf begin ist alles gleich
//kann man das vereinheitlichen?
beginMethod(arg, (iar) =>
{
try
{
var result = endMethod(iar);
tcs.TrySetResult(result);
}
catch (OperationCanceledException ex)
{
tcs.TrySetCanceled();
}
catch (Exception ex)
{
if (skipExceptions == null || skipExceptions.Count == 0)
tcs.TrySetException(ex);
else
{
Type exType = ex.GetType();
for (int i = 0; i < skipExceptions.Count; i++)
{
if (skipExceptions[i].IsAssignableFrom(exType))
{
tcs.TrySetResult(default(TResult));
break;
}
}
}
}
}, state);
}
catch
{
tcs.TrySetResult(default(TResult));
throw;
}
return tcs.Task;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment