developer tip

C #의 Promise에 해당

copycodes 2021. 1. 7. 08:07
반응형

C #의 Promise에 해당


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);

"시간이 지정된 비동기 대기"는 약간 어색하지만 실제 코드에서도 비교적 드물다. 단위 테스트의 경우 정기적 인 비동기 대기를 수행합니다.

var promise = new TaskCompletionSource<MyResult>();

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

var myResult = await promise.Task;

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

타사 라이브러리가없는 대략적인 C #은 다음과 같습니다.

// var MyResult has a field `Header`
var promise = new TaskCompletionSource<MyResult>();

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

// Wait for 2 seconds
if (promise.Task.Wait(2000))
{
  var myResult = promise.Task.Result;
  Debug.Assert("my header" == myResult.Header);
}

일반적으로 await/ async를 가능한 한 높은 수준으로 사용하는 것이 가장 좋습니다 . Resulta Task또는 using에 액세스하면 Wait경우에 따라 교착 상태가 발생할 수 있습니다 .


C # Promises 라이브러리를 사용할 수 있습니다.

Github에서 오픈 소스 : https://github.com/Real-Serious-Games/C-Sharp-Promise

NuGet에서 사용 가능 : https://www.nuget.org/packages/RSG.Promise/


비동기 모델을 살펴보십시오. 작업은 C #에서 가장 가깝습니다.

다음은 그 사용을 설명하는 MS 문서에 대한 링크입니다.


This is the old school way of doing Promises.
Back then i believe it was called synchronization :)

MyResult result = null;
var are = new AutoResetEvent(false);

handlerMyEventsWithHandler( 
    msg => {result = msg; are.Set();}
);

// Wait for 2 seconds
if(!are.WaitOne(2000)) {/* handle timeout... */}

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

Just for Completeness - to large for a comment.
I agree with Stephen Cleary's answer.

But if you are building a facade around some legacy code this can be used to wrap old API's in a Task like:

public Task<MyResult> GetResultAsync() {
    MyResult result = null;
    var are = new AutoResetEvent(false);
    handlerMyEventsWithHandler(msg => {
        result = msg;
        are.Set();
    });
    are.WaitOne();
    return Task.FromResult(result);
}

ReferenceURL : https://stackoverflow.com/questions/38996593/promise-equivalent-in-c-sharp

반응형