0

class WorkerTaskEvent : IDisposabletype のプロパティを持つ がありますTask。作成時に、ある時点で終了するはずのバックグラウンドで何らかのメソッドを実行する新しいタスクが作成されます。
ただし、タスクが終了しないことがあるため、物事が永久にメモリに保持されます。現在、キャンセル トークンを使用してキャンセル メッセージを送信しています。これは次のように行います。

public WorkerTaskEvent(ExecuteTaskMethod taskMethod)
{
    TaskMethod = taskMethod;
    RunningTask = Task.Factory.StartNew(OnExecuteTask, Token.Token); 
}

private void OnExecuteTask()
{
    if (TaskMethod != null) TaskMethod();
}

public void Dispose()
{
    if (RunningTask != null && !RunningTask.IsCompleted)
    {
        Token.CancelAfter(TimeSpan.FromMinutes(1));
    }
}

(タスクが特定の時間内に終了するかどうかを確認するコードを含む、より多くのコードがあります。)
このタスクを永久に実行することはできません。これが適切な解決策であることを願っていますが、おそらく他の誰かがより良いオプションを持っていますか?
私は TaskMethod が正確に何をするかをまったく制御できないので、このメソッドが強制終了されたときにリソースが失われたとしても問題ありません。ただし、完璧にはほど遠いです。ただし、クリーンアップは、このデリゲートの背後にあるメソッドを作成する人の責任になります。

委任されたメソッドにキャンセル トークンを渡すことは大いに役立つかもしれませんが、委任されたメソッドはサードパーティ ライブラリの一部であり、無限ループで終了することは想定されていないため、これを解決策として使用することはできません。デリゲートはエンドレスにループする傾向があるため、マーフィーの法則は再び私の顔を笑わせています。このライブラリの次のバージョンでキャンセル トークンを渡すことができるかもしれませんが (私はこれを要求しました)、今のところ、無限ループを止めるのは難しい方法です...

4

1 に答える 1

1

タスクのキャンセルは協調的であり、強制されるべきではありません。

キャンセル トークンを渡すTask.Factory.StartNew()のは、タスクが実際にスケジュールされる前でもトークン ソースがキャンセルされた場合です。ただし、タスクの実行が開始されたら、キャンセルされたトークンを確認して停止するのは、実行中のデリゲートの責任です。

ExecuteTaskMethodしたがって、CancellationToken パラメーターを受け入れるようにデリゲートを定義する必要があります。次に、デリゲートの実装者に任せて、トークンをキャンセルします。

private void OnExecuteTask()
{
    if (TaskMethod != null) TaskMethod(Token.Token);
}

こちらの回答も参照してください: TPL タスクを中止/キャンセルするにはどうすればよいですか?

于 2013-07-18T19:26:32.823 に答える