编辑:
如果您想在不阻塞线程的情况下执行此操作,可以使用以下方法执行以下操作TaskCompletionSource<T>
:
var completionSource = new TaskCompletionSource<T>();
var requestIdentifier = Guid.NewGuid();
EventHandler<ResponseEventArgs> handler = null;
handler = (sender, args) =>
{
if(args.RequestIdentifier == requestIdentifier)
{
api.ResponseReceived -= handler;
// TrySetResult avoids re-entrancy problems in case of an
// API that sends duplicates, but there other ways of
// dealing with this too.
completionSource.TrySetResult((T)args.Response);
}
};
api.ResponseReceived += handler;
// Make this async if you want.
api.SendRequest(requestIdentifier, request);
return completionSource.Task;
原答案:
我认为您想要类似以下的内容,它使用 aManualResetEvent
来阻止线程,直到 API 引发事件:
return Task.Factory.StartNew<T>(() =>
{
var waitHandle = new ManualResetEvent(false);
T result = default(T);
var requestIdentifier = Guid.NewGuid();
EventHandler<ResponseEventArgs> handler = (sender, args) =>
{
if(args.RequestIdentifier == requestIdentifier)
{
result = (T)args.Response; // Not sure how this looks in your API
waitHandle.Set(); // Unblock the thread running the task
}
};
// Attach handler to respond to the response being received.
api.ResponseReceived += handler;
// Send request off.
api.SendRequest(requestIdentifier, request);
// Wait until response is received.
waitHandle.WaitOne();
// Detach handler to prevent leak.
api.ResponseReceived -= handler;
return result;
});
要获得更简洁的方法,请查看Reactive Extensions。