私は、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メソッドを呼び出すと、私は例外であると言っています。
約束事スタイルのタスクではStartを呼び出すことはできません。
.NETは特別な種類のタスク(約束事のタスク)を区別している可能性が非常に高いです。要約すると
は私の質問は以下のとおりです。
これらの約束スタイルのタスクが何を意味するのですか?
私は何をしたいのですか?
アンラップは、あなたが思うとは思いません。コールドタスクを開始することはできません.Unwrap()コールの後に参照を失いました。この関数は単純に 'public static async Task Unwrap(this Task >タスク){return await task; } '内部の' awaitタスク 'は、あなたがその外部タスクを開始する方法を失ったため決して完了しません。 –
@ScottChamberlain私はこのように考えていません。だから私はUnwrapによって返されたタスクでStartを呼び出そうとしたのです。 – Dobby007