我正在尝试编写一个返回任务的C#方法。任务应该注册到另一个对象上的事件(我没有写入并且不能控制)并在触发事件时完成。事件args包含任务的结果。
我尝试了以下想法(这很糟糕......):
public Task<int> GetValue(ObjectToWaitFor waitFor)
{
var flag = false;
int value = -1;
return Task.Factory.StartNew<int>(() =>
{
waitFor.TheEvent += (s, e) =>
{
value = e.Value;
flag = true;
};
while (!flag)
{
Task.Delay(100).Wait();
}
return value;
});
}
使用一个标志,在事件处理程序中设置为true,然后让任务循环直到该标志设置为true。但它似乎不是一个优雅的解决方案,我想知道是否有更好的方法。
答案 0 :(得分:3)
扩展@jonskeet的回答:
void Main()
{
var foo = new Foo();
//type parameter here defines the type of the Task
//so here, we're expecting to make a Task<int>
var tcs = new TaskCompletionSource<int>();
foo.Evt += (sender, eventArgs) => {
tcs.SetResult(0);
//or tcs.SetException(someException);
//etc...
};
//here's your task, ready to go.
Task<int> task = tcs.Task;
}
class Foo
{
public event EventHandler Evt;
}
答案 1 :(得分:1)
我怀疑你正在寻找TaskCompletionSource<TResult>
。基本上,您创建其中一个(并记住它),并将其在Task
属性中提供的任务交还。
触发事件时,在完成源上设置适当的结果/错误,然后就完成了。