c#-如何形成TaskCompletionSource的集合并保持类型安全
作者:互联网
我有一些异步方法:
// not ideal
private TaskCompletionSource<A> _tcsA;
private TaskCompletionSource<A> _tcsB;
private TaskCompletionSource<A> _tcsC;
...
public Task<A> GetAAsync() {
_currentTask = TaskType.A;
_tcsA = new TaskCompletionSource<A>();
// some complex non-sync task, using http/events that ends with Complete();
// QueueRequest?.Invoke(this, taskInfo); // raise request -- this does not return
return _tcsA.Task;
}
public Task<B> GetBAsync() {
_currentTask = TaskType.B;
_tcsB = new TaskCompletionSource<B>();
// some complex non-sync task, using http/events that ends with Complete();
// QueueRequest?.Invoke(this, taskInfo); // raise request -- this does not return
return _tcsB.Task;
}
public Task<C> GetCAsync() {
_currentTask = TaskType.C;
_tcsC = new TaskCompletionSource<C>();
// some complex non-sync task, using http/events that ends with Complete();
// QueueRequest?.Invoke(this, taskInfo); // raise request -- this does not return
return _tcsC.Task;
}
// called by an external source, a http listener / processor
// this should complete the async call by the client and return results
public void Complete(Result result) {
switch (_currentTask) {
case TaskType.A:
_tcsA.SetResult(new A());
break;
case TaskType.B:
_tcsB.SetResult(new B());
break;
case TaskType.C:
_tcsC.SetResult(new C());
break;
}
_currentTask = TaskType.None;
}
为了简单起见,以上是半伪代码.我称这样的方法之一:
一个=等待服务.GetAAsync();
现在的问题是TaskCompletionSource< T>.是通用的,如果我有100种方法,则必须为每种返回类型创建一个变量.但是,由于一次只能调用一种方法,因此最好使用单个TaskCompletionSource,但不要将其键入对象(TaskCompletionSource< object>).
我不想做:
对象a =等待service.GetAAsync();
因为那将需要客户强制转换.因此,最好的解决方案是只有一个TaskCompletionSource,但以某种方式键入它.或者,也可以具有TaskCompletionSource字典.两者对我来说似乎都是不可能的.
我该如何解决?
更新:
有关我的情况的背景信息,请查看:Wrap synchronous code into async await in disconnected scenario
解决方法:
I don’t want to do
object a = await service.GetAAsync()
because that will need casting by the client.
不必要.保留相同的签名,但添加对ContinueWith的调用以强制转换为适当的类型:
public Task<A> GetAAsync() {
_currentTask = TaskType.A;
_tcs = new TaskCompletionSource<object>();
// some complex task that ends with Complete();
return _tcs.Task.ContinueWith(t => (A)t.Result);
}
或者,您也可以使用async / await执行相同的操作:
public async Task<A> GetAAsync() {
_currentTask = TaskType.A;
_tcs = new TaskCompletionSource<object>();
// some complex task that ends with Complete();
return (A)await _tcs.Task;
}
标签:async-await,casting,generics,taskcompletionsource,c 来源: https://codeday.me/bug/20191108/2005980.html