更新:私のNito.AsyncExライブラリにはTeamFoundationClientAsyncFactory
型が含まれるようになりました。これは、以下の独自の実装をローリングする代わりに使用できます。
TFS API はパラメーターをとらないため、APM パターンに厳密に従っていません。state
これにより、ビルトインが機能しなくなりますTaskFactory.FromAsync
。
独自の同等のものを作成する必要があります。これは、次FromAsync
を使用して実行できますTaskCompletionSource
。
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.Client;
public static class TfsUtils<TResult>
{
public static Task<TResult> FromTfsApm(Func<AsyncCallback, ICancelableAsyncResult> beginMethod, Func<ICancelableAsyncResult, TResult> endMethod, CancellationToken token)
{
// Represent the asynchronous operation by a manually-controlled task.
TaskCompletionSource<TResult> tcs = new TaskCompletionSource<TResult>();
try
{
// Begin the TFS asynchronous operation.
var asyncResult = beginMethod(Callback(endMethod, tcs));
// If our CancellationToken is signalled, cancel the TFS operation.
token.Register(asyncResult.Cancel, false);
}
catch (Exception ex)
{
// If there is any error starting the TFS operation, pass it to the task.
tcs.TrySetException(ex);
}
// Return the manually-controlled task.
return tcs.Task;
}
private static AsyncCallback Callback(Func<ICancelableAsyncResult, TResult> endMethod, TaskCompletionSource<TResult> tcs)
{
// This delegate will be invoked when the TFS operation completes.
return asyncResult =>
{
var cancelableAsyncResult = (ICancelableAsyncResult)asyncResult;
// First check if we were canceled, and cancel our task if we were.
if (cancelableAsyncResult.IsCanceled)
tcs.TrySetCanceled();
else
{
try
{
// Call the TFS End* method to get the result, and place it in the task.
tcs.TrySetResult(endMethod(cancelableAsyncResult));
}
catch (Exception ex)
{
// Place the TFS operation error in the task.
tcs.TrySetException(ex);
}
}
};
}
}
その後、次のように拡張メソッドで使用できます。
using System.Threading;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
public static class TfsExtensions
{
public static Task<WorkItemCollection> QueryAsync(this Query query, CancellationToken token = new CancellationToken())
{
return TfsUtils<WorkItemCollection>.FromTfsApm(query.BeginQuery, query.EndQuery, token);
}
}