1

ボタンのクリックから起動されるバックグラウンド非同期タスクがあります。IsBusyタスクの開始時に更新され、キャンセルまたは完了を説明するためにfinallyブロック内にあるプロパティがあります。

現在、ボタンクリックイベントは前のタスクをキャンセルし、再度クリックすると新しいタスクを開始します。ただし、最初のタスクのキャンセルは新しいタスクの開始後も長引く可能性があるため、ブールIsBusyインジケーターが同期しなくなる可能性があります。

私の問題は、この状況にどう対処するかです。

私の現在の解決策は、ブール値を直接更新するのではなく、開始時と完了時にインクリメント/デクリメントされる整数を使用することです-IsBusyプロパティはを返しBusyCount > 0ます。ただし、これにはスレッドセーフのための追加が必要であり、良い解決策とは思えません。

もう1つの考えは、タスクが実行されたときにタスクを保存し、最初のタスクの続きとしてのみ新しいタスクを開始することでした。これはキャンセルの問題を説明しますが、タスクではなく呼び出し元に不必要な遅延(ただし部分的)と「契約」を強制します。

私の最終的な考えは、スレッドセーフなコレクションに追加/削除される使い捨てのBusyTokenを配布するBusyTokenSourceクラスのようなものを作成することでした。しかし、これはやり過ぎのようです。

このタイプの状況を処理するためのより良い/適切な/一般的な方法はありますか?

編集:

私は上記の最後の考えに行き着き、「BusyToken」クラスを作成しました。このようにして、関数をaでラップしusing(BusyTokenSource.GetToken()){}、内部コレクションを実行Disposeして、カウントとビジー状態を処理することができます。

4

1 に答える 1

2

タスクごとに 1 つのビジー ステータスが必要だと思います。あなたのBusyTokenSourceアイデアがどのように機能するかはわかりませんが、少し似ているように聞こえます。

ホルダー クラスを作成します。

class BusyStatus { bool IsBusy; }

そして、開始する各タスクにその新しいインスタンスを与えます。古いタスクに関心がなくなったら、古い BusyStatus を破棄して新しいインスタンスを作成します。古いタスクは最終的に終了し、ビジー状態になりますが、古いインスタンスでは誰も使用しなくなります。

古いタスクが誤って新しいBusyStatusインスタンスを参照しないようにしてください。

より一般的なルールとして、各タスク (またはスレッド) を個別のデータ構造で動作させると便利なことがよくあります。これは有用な一般的な指針です。これにより、シンプルさが得られ、安全性を簡単に実現できます。

于 2012-09-27T20:49:56.830 に答える