1

私はReliableQueue<MyTask>を別のスコープでエンキューしていますが、トランザクション内のタスクをデキューしています。中断されたトランザクションの非同期状態を保存するためのステートフルサービス内のネストされたトランザクション

ここでの問題は、私のキュートランザクションが中止された場合、長い計算のインスタンスを失いたくないということです。それは独立したバックグラウンドで実行し続けます。タスクの処理を再試行したら、完了したかどうかを確認したいだけです。

コード・セグメント:

public void protected override async Task RunAsync(CancellationToken cancellationToken) 
{ 
    var queue = await StateManager.GetOrAddAsync<IReliableQueue<MyTask>>(...); 
    while(!cancellationToken.IsCancellationRequested) 
    { 
     using (var transaction = ...) 
     { 
      var myTaskConditional = await queue.TryDequeueAsync(transaction); 
      if (!myTaskConditional.HasValue) 
      { 
       break; 
      } 
      await DoLongProcessing(myTaskConditional) 
      await transaction.CommitAsync(); 
     } 
    } 
} 

private async void DoLongProcessing(MyTask myTask) { 
    var dict = await StateManager.GetOrAddAsync<IReliableDictionary<Guid,Guid>>(...); 
    Conditional<Guid> guidConditional; 
    using (var transaction = ...) 
    { 
     guidConditional = await dict.TryGetValueAsync(myTask.TaskGuid); 
     if (guidConditional.HasValue) { 
      await transaction.CommitAsync(); 
      // continue handling knowing we already started, continue to wait for 
      await WaitForClaulcationFinish(guidConditional.Value); 
     } 
     else { 
      // start handling knowing we never handled this task, create new guid and store it in dict 
      var runGuid = await StartRunningCalculation(runGuid); 
      await dict.AddAsync(myTask.TaskGuid, runGuid); 
      await transaction.CommitAsync(); 
      await WaitForClaulcationFinish(runGuid); 
     } 
    } 
} 

私の関心:私はネストされたトランザクションを使用していますし、それはお勧めしません。

ReliableQueueまたはReliableDictionaryのトランザクションを単独で使用している場合、実際にデッドロックが発生する危険性はありますか?

私が達成しようとしているもののより良い意図されたデザインがありますか?

+0

「StartRunningCalculation」とは何ですか? @FrancescoB。 –

+0

それは長い計算でPythonスクリプトを実行しています – Mugen

答えて

1

トランザクション内で長時間実行してはいけません。私が公開したpriority queue serviceを見てください。作業中にアイテムをキューに入れてコレクションに入れ、完了したらキューに戻すか、作業を完了します。

関連する問題