[英]How to call an async method inside a manually created task?
I need to implement something like a cold observable object in RxJS (just a standard Observable). 我需要在RxJS中实现类似冷的可观察对象(只是一个标准的可观察对象)。 I need to call an async method inside a task I create myself via constructor (new Task()).
我需要在通过构造函数(new Task())创建自己的任务中调用异步方法。 I need to implement this because before executing any asynchronous code I want to do some stuff which is very specific to my project.
我需要实现它,因为在执行任何异步代码之前,我想做一些非常特定于我的项目的工作。 So I want to recieve a task that is not started yet which I can start manually a little bit later.
因此,我想接收一个尚未开始的任务,稍后可以手动开始。
So far I came to the following decision and to my surprise it isn't working! 到目前为止,我做出了以下决定,令我惊讶的是,这没有用!
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();
}
}
It seems that calling Unwrap or using TaskCompletionSource creates a task in a WaitingForActivation state. 似乎调用Unwrap或使用TaskCompletionSource会创建处于WaitingForActivation状态的任务。 And calling Start method on tasks in this state leads me to the exception which is saying:
在这种状态下,对任务调用Start方法会导致出现异常:
Start may not be called on a promise-style task.
在约定样式的任务上可能不会调用启动。
So it's very likely that .NET distinguishes special kind of tasks - promise-style tasks. 因此,.NET很可能区分特殊类型的任务-承诺式任务。
In summary my questions are: 总而言之,我的问题是:
What do these promise-style tasks mean? 这些诺言式任务是什么意思?
How can I do what I want to do? 我该怎么做我想做的事?
Promise style tasks are tasks that are not based on threads, they are based on events, For a TaskCompletionSource
the "event" is the act of calling SetResult
, SetCanceled
or SetException
承诺式任务是不基于线程的任务,它们基于事件,对于
TaskCompletionSource
,“事件”是调用SetResult
, SetCanceled
或SetException
To receive a task that is not started yet which you can start manually a little bit later, simply hold on to the Func<Task<T>>
and you evaluate the function to start up the task at the later point in time. 要接收尚未开始的任务,您可以稍后手动启动它,只需按住
Func<Task<T>>
然后评估该函数以在以后的时间点启动该任务。 This can be done quite simply. 这可以很简单地完成。
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.
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.