2016-08-07 15 views
2

The Top 7 Mistakes Newbies Make with Akka.NETは説明する:アッカ.NET PipeTo()()

[...]我々は、エンドユーザーがネストされた非同期の多くを開発参照/個々のメッセージハンドラ内で操作を待機します。ほとんどのユーザーは、これを行うために見過ごされるコストがあります。アクターは、待っているメッセージが元のメッセージの「一度に1つのメッセージ」の一部であるため、各操作の間に他のメッセージを処理できません。

はまだPetabridgeアッカ.NET合宿のUnit 3 Lesson 4に、この例では大丈夫と考えられている:私はこれを理解

// asynchronously download the image and pipe the results to ourself 
_httpClient.GetAsync(imageUrl).ContinueWith(httpRequest => 
{ 
    var response = httpRequest.Result; 

    // successful img download 
    if (response.StatusCode == HttpStatusCode.OK) 
    { 
     var contentStream = response.Content.ReadAsStreamAsync(); 
     try 
     { 
      contentStream.Wait(TimeSpan.FromSeconds(1)); 
      return new ImageDownloadResult(image, 
       response.StatusCode, contentStream.Result); 
     } 
     catch //timeout exceptions! 
     { 
      return new ImageDownloadResult(image, HttpStatusCode.PartialContent); 
     } 
    } 

    return new ImageDownloadResult(image, response.StatusCode); 
}, 
    TaskContinuationOptions.ExecuteSynchronously) 
.PipeTo(Self); 

方法、俳優がGetAsync()まで、他のすべてのメッセージを処理することができず、 が完了しました。これはまさに問題です。回避しようとしていたPipeTo()

ここに何か不足していますか?

+0

可能な重複http://stackoverflow.com/questions/28550275/async-api-call-アクター内外の例外) – tomliversidge

答えて

0

私が考えているのは、GetAsync()が待たれていないので、すべてが非同期で起動し、実行をブロックしないということです。

このすべてが起こっている間も、俳優は自由に追加のメッセージを処理できます。

+0

はい、http://stackoverflow.com/questions/28550275/async-api-call-inside-anactor-and-exceptionsを読んだ後、同意します。これは重複している可能性も考えます – tomliversidge

0

TaskContinuationOptions.ExecuteSynchronouslyは、ContinueWithが完了するためにタスクを遷移させるコードでsinchronouslyを実行することを意味します(TaskContinuationOptions)。

このコードのコードは、ContinueWith()PipeTo()というセットアップを実行して戻ります。俳優は自由に新しいメッセージを受け取ることができ、タスクが完了するとPipeTo()はそれに結果のメッセージを送ります。

ジジが言及しているように、タスクが俳優で待たされた場合、それはブロックされます。

ContinueWith()もタスクを返し、それはPipeTo()が動作すると考えるのが役立ちます。

これはAkka.net GithubでPipeToの拡張子です:

public static Task PipeTo<T>(this Task<T> taskToPipe, ICanTell recipient, IActorRef sender = null, Func<T, object> success = null, Func<Exception, object> failure = null) 
    { 
     sender = sender ?? ActorRefs.NoSender; 
     return taskToPipe.ContinueWith(tresult => 
     { 
      if (tresult.IsCanceled || tresult.IsFaulted) 
       recipient.Tell(failure != null 
        ? failure(tresult.Exception) 
        : new Status.Failure(tresult.Exception), sender); 
      else if (tresult.IsCompleted) 
       recipient.Tell(success != null 
        ? success(tresult.Result) 
        : tresult.Result, sender); 
     }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); 
    } 
([俳優や例外内部の非同期API呼び出し]の
関連する問題