私は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
のトランザクションを単独で使用している場合、実際にデッドロックが発生する危険性はありますか?
私が達成しようとしているもののより良い意図されたデザインがありますか?
「StartRunningCalculation」とは何ですか? @FrancescoB。 –
それは長い計算でPythonスクリプトを実行しています – Mugen