我有一个功能:
int f1(int a)
{
return a;
}
int f2(int a)
{
return a*2;
}
我希望执行函数异步和并行,等待结果并求和结果。我可以使用代码
var result1 = Task.Run(() => f1(5));
var result2 = Task.Run(() => f2(10));
await Task.WhenAll(result1, result2);
int result = result1.Result + result2.Result;
很酷。但是,如果我的函数使用回调
,该怎么办?void f1(Action<int> action, int a)
{
action.Invoke(a);
}
void f2(Action<int> action, int a)
{
a = a*2;
action.Invoke(a);
}
f1(result => Console.WriteLine("result1 = {0}", result), 5);
f2(result => Console.WriteLine("result2 = {0}", result), 10);
我不能重写这个函数,这个函数在其他代码中使用。在这种情况下,我可以解决我的代码不像地狱的问题吗?
答案 0 :(得分:5)
var tcs1 = new TaskCompletionSource<int>();
var tcs2 = new TaskCompletionSource<int>();
f1( (x) => { tcs1.SetResult(x); }, 5);
f2( (x) => { tcs2.SetResult(x); }, 10);
var results = await Task.WhenAll(tcs1.Task, tcs2.Task);
int result = results[0] + results[1];
答案 1 :(得分:3)
您可以使用TaskCompletionSource
类创建一个任务,该任务表示基于回调的异步方法(或基于事件的异步方法或任何其他非基于Task
的异步方法)的完成在那里):
var f1CompletionSource = new TaskCompletionSource<int>();
var f2CompletionSource = new TaskCompletionSource<int>();
Task.Run(() => foo.f1(n => f1CompletionSource.TrySetResult(n), 5));
Task.Run(() => foo.f2(n => f2CompletionSource.TrySetResult(n), 10));
await Task.WhenAll(f1CompletionSource.Task,
f2CompletionSource.Task);
int result = f1CompletionSource.Task.Result +
f2CompletionSource.Task.Result;
此处不清楚您是否希望通过f1
调用f2
和Task.Run
。你提供的方法是同步完成的,而不是异步的,但如果你在这里建模的实际方法是异步工作,那么就不需要Task.Run
。