待機時間の経過後にSQL問合せを実行しているタスクのリストを取り消す必要があります。 CancellationTokenを実装してタスクをキャンセルすることができます。しかし、取り消しは協調的なものなので、すべてのステップの前に自分のアクション内で取り消しトークンのステータスを確認する必要があります。しかし、私の場合、SQLクエリは長い時間がかかりますが、クエリの実行前後にキャンセルトークンの状態を確認することしかできません。後のケースでは役に立たないので、キャンセルトークンのステータスに基づいてこれらのタスクの中でクエリの実行をキャンセルするにはどうすればよいですか?C#長時間実行されているSQL問合せを実行中のタスクのリストを取り消します。
public void EnqueueTask(Action action, CancellationToken cancelToken = default(CancellationToken))
{
var task = new Task(action, cancelToken, TaskCreationOptions.LongRunning);
if (_workTaskQueue.TryAdd(task))
{
TaskHandler?.Invoke
(new TaskProcessingArguments
{
ISTaskAdded = true,
Message = "Task Added to Queue",
PendingTaskCount = _workTaskQueue.Count,
});
}
else
{
TaskHandler?.Invoke
(new TaskProcessingArguments
{
ISTaskAdded = false,
Message = "Timedout while adding Task to Queue",
PendingTaskCount = _workTaskQueue.Count,
});
}
}
public void DequeueTask(int maxConcurrency, CancellationToken ct)
{
var tasks = new List<Task>();
using (SemaphoreSlim concurrencySemaphore = new SemaphoreSlim(maxConcurrency))
{
foreach (var task in _workTaskQueue.GetConsumingEnumerable())
{
try
{
if (!(task.IsCanceled) && task.Status == TaskStatus.Created)
{
tasks.Add(task);
task.Start();
}
}
finally {
concurrencySemaphore.Release();
}
}
}
Task.WaitAll(tasks.ToArray());
}
void StartWorker()
{
Task.Factory.StartNew(() =>
{
try
{
taskQueue.DequeueTask(maxConcurrency, cancellationToken);
}
finally {
lock (syncObj)
{
IsCompleted = true;
}
//Logger.Info("Closing Worker task!!!");
}
}, TaskCreationOptions.LongRunning);
}
、何をquerysを実行するために使用しますか? cancelTokenをパラメータとしてasyncメソッドに渡すことが可能な場合もあります。 覚えていること:特定の時間の後にSQLクエリをキャンセルすると、クエリが実行された場所(およびキャンセルトークンではない)にタイムアウト(ミリ秒)を渡す方がよいでしょう。あなたが知っていない場合にのみ、cancelationtokenを使用します。停止する場合(例:ユーザーが停止したい場合) – maerlin
Maerlin、サンプルコードを追加しました。私はすでにSQLクエリのための個々のタイムアウトを持っていますが、私はセマフォを使用して小さなバッチでタスクを実行しているので、10秒後にバッチタイムアウトの各クエリと10バッチがあり、100秒10秒後にすべてのタスクの実行をキャンセルしたいと考えています。 – Nitheesh
非同期操作 –