1. ホーム
  2. c#

[解決済み] C#におけるPromiseの等価性

2023-05-03 20:37:45

質問

Scalaでは、手動でFutureを完了するために使用される可能性のあるPromiseクラスがあります。私はC#で代替品を探しています。

私はテストを書いており、私はそれがこのように見えるようにしたいです。

// var MyResult has a field `Header`
var promise = new Promise<MyResult>;

handlerMyEventsWithHandler( msg =>
    promise.Complete(msg);
);

// Wait for 2 seconds
var myResult = promise.Future.Await(2000);

Assert.Equals("my header", myResult.Header);

これはおそらくC#のパターンとしては適切でないことは理解していますが、多少異なるパターンでも同じことを実現する合理的な方法を見つけ出すことができませんでした。

編集: 注意してほしいのは、その async / await は、ここでは役に立ちません。私はただ、別のスレッドで実行されるハンドラへのアクセスを持っているだけです。

どのように解決するのですか?

C#の場合。

  • Task<T> は未来(または Task はユニットリターンフューチャー)。
  • TaskCompletionSource<T> はプロミスです。

ですから、あなたのコードは次のように翻訳されます。

// var promise = new Promise<MyResult>;
var promise = new TaskCompletionSource<MyResult>();

// handlerMyEventsWithHandler(msg => promise.Complete(msg););
handlerMyEventsWithHandler(msg => promise.TrySetResult(msg));

// var myResult = promise.Future.Await(2000);
var completed = await Task.WhenAny(promise.Task, Task.Delay(2000));
if (completed == promise.Task)
  ; // Do something on timeout
var myResult = await completed;

Assert.Equals("my header", myResult.Header);

timeed asynchronous wait"は少し厄介ですが、現実のコードでは比較的珍しいものです。ユニットテストでは、私なら通常の非同期待ちを行います。

var promise = new TaskCompletionSource<MyResult>();

handlerMyEventsWithHandler(msg => promise.TrySetResult(msg));

var myResult = await promise.Task;

Assert.Equals("my header", myResult.Header);