我需要在RxJS中实现类似冷可观察对象的东西(只是一个标准的Observable)。我需要在我通过构造函数创建的任务中调用异步方法(new Task())。我需要实现这个,因为在执行任何异步代码之前,我想做一些非常特定于我的项目的东西。所以我想收到一个尚未启动的任务,我可以稍后手动启动。
到目前为止,我做出了以下决定,令我惊讶的是它不起作用!
class Program
{
static void Main(string[] args)
{
var task1 = CallApi(() => t.Go());
var task2 = CallApi2(() => t.Go());
task1.Start();
task2.Start();
}
public static Task<T> CallApi<T>(Func<Task<T>> function)
{
if (function == null)
{
throw new ArgumentNullException(nameof(function));
}
return new Task<Task<T>>(async () =>
{
return await function();
}).Unwrap();
}
public static Task<T> CallApi2<T>(Func<Task<T>> function)
{
if (function == null)
{
throw new ArgumentNullException(nameof(function));
}
var tcs = new TaskCompletionSource<T>();
var resultTask = new Task<Task<T>>(() =>
{
var t = function();
t.ContinueWith(
task => {
tcs.SetResult(task.Result);
},
TaskContinuationOptions.OnlyOnRanToCompletion
);
t.ContinueWith(
task => {
tcs.SetCanceled();
},
TaskContinuationOptions.OnlyOnCanceled
);
t.ContinueWith(
task => {
tcs.SetException(task.Exception);
},
TaskContinuationOptions.OnlyOnFaulted
);
return tcs.Task;
});
return resultTask.Unwrap();
}
}
调用Unwrap或使用TaskCompletionSource似乎在WaitingForActivation状态下创建一个任务。在这种状态下调用任务上的Start方法会引发我的异常,即:
启动可能不会在承诺式任务上调用。
因此,.NET很可能区分特殊类型的任务 - 承诺式任务。
总之,我的问题是:
这些承诺风格的任务是什么意思?
我怎样才能做我想做的事?
答案 0 :(得分:2)
Promise样式任务是不基于线程的任务,它们基于事件,对于TaskCompletionSource
&#34;事件&#34;是调用SetResult
,SetCanceled
或SetException
要接收尚未启动的任务,您可以稍后手动启动,只需按住Func<Task<T>>
,然后评估该功能以便在以后的某个时间启动任务。这可以很简单地完成。
public void Example()
{
Func<Task<T>> func1 = () => t.Go();
//Do other work
Task<T> task1 = func1(); //t.Go() is not called until this point then the task starts.
}