1

Windows サービス (.net 4.0) での大きなファイルの処理とアップロードを扱っています。プロセスとアップロードの手順が完了するまでに数分かかる場合があります。管理者はジョブをデータベースで直接キャンセル済みとしてマークすることができますが、メモリ キューでクリアするにはサービスの再起動が必要です。目標は、そのジョブを破棄し、サービスを再起動せずにキュー内の次のジョブを選択することです。これが私がやりたいことです:

メイン エントリ ポイントで、次の 2 つのタスクを開始します。

Task processTask = Task.Factory.StartNew(ProcessJob);

Task monitorTask = Task.Factory.StartNew(MonitorDB);

ProcessJob は、ProcessFile、UploadFile などの複数の実行時間の長いステップを呼び出します。ステップ間のジョブ ステータスを確認していますが、これらの実行時間の長いステップのいずれかでジョブがスタックしている可能性があります。

monitorTask が DB でジョブ ステータスの変化を検出した場合、それを (例外またはメッセージを介して) メイン スレッドに通知し、メイン スレッドが終了して処理キューから自身を削除し、キュー内の次のジョブを開始できるようにする必要があります。待機なしでは例外に到達できませんが、これらのタスクを並行して実行する必要があるため待機できません。現時点では、ProcessJob の一部の同期ステップがまだ進行中であり、最終的に完了する可能性があるという事実には関心がありません。それをコードで処理します。

これまでのすべてのアプリケーションで、成功と失敗に Task.ContinueWith を使用してきましたが、メイン スレッドと通信する必要はありませんでした。

4

2 に答える 2

3

を介して、モニター スレッドとメイン スレッドの間で通信できますBlockingCollection<T>

これは私が書いた簡単な例です。

BlockingCollection<string> queue =
    new BlockingCollection<string>();

// monitor thread.
Task.Factory.StartNew(() =>
{
    while (true)
    {
        Thread.Sleep(1000);
        queue.Add("event occured.");
    }
});

// main thread.
while (true)
{
    // blocks when no messages are in queue.
    string message = queue.Take();

    // kill process thread here.
}
于 2012-05-30T15:46:07.083 に答える
1

これには aCancellationTokenを使用できます。クラスを見ると、Taskを渡すことができるオーバーロードがありますCancellationToken。このトークンへの参照をサービスに保存し、トークンがキャンセルされたかどうかをアップロード/プロセス ルーチンに定期的にチェックさせるだけです。

if (yourToken.IsCancellationRequested)
    break;
于 2012-05-30T15:42:55.513 に答える