私のプログラムは、Web サイトからリアルタイム データを要求します。このデータはいつでも変更される可能性があるため、変更を監視するために繰り返し頻繁にリクエストする必要があります。データは、いくつかの移動平均とともにヒストグラムとして Windows フォーム チャートに表示されます。この情報に基づいて、ユーザーはフォームを操作してプログラムの一部のパラメーターを設定し、受信データに基づいてアクションを実行できる必要があります。このデータをどのように処理すればよいですか? 私の現在の計画は、データを収集してメインフォームに書き込む別のスレッドを用意することですが、A) インターフェイスを応答しなくし、B) 別のスレッドを開始することなく、そのデータの変更を監視する方法がわかりません。A は明らかな理由で受け入れられません。BI を実行する場合は、データを収集しているスレッドにそのコードをスローするだけでよいと思います。
質問する
2934 次
2 に答える
2
この場合にすべきことは、ワーカー スレッドに Web サイトのポーリングを実行させ、見つかったすべてのデータをConcurrentQueue
. 次に、UI スレッドでこのキューを定期的にポーリングして、新しいデータを取得します。そのワーカー スレッドが UI スレッドとまったくやり取りする必要はありません。Control.Invoke
このような状況では、または他のマーシャリング手法を使用しないでください。
public class YourForm : Form
{
private CancellationTokenSource cts = new CancellationTokenSource();
private ConcurrentQueue<YourData> queue = new ConcurrentQueue<YourData>();
private void YourForm_Load(object sender, EventArgs args)
{
Task.Factory.StartNew(Worker, TaskCreationOptions.LongRunning);
}
private void UpdateTimer_Tick(object sender, EventArgs args)
{
YourData item;
while (queue.TryDequeue(out item))
{
// Update the chart here.
}
}
private void Worker()
{
CancellationToken cancellation = cts.Token;
while (!cancellation.WaitHandle.WaitOne(YOUR_POLLING_INTERVAL))
{
YourData item = GetData();
queue.Enqueue(item);
}
}
}
上記の例は WinForms に基づいていますが、同じプリンシパルが WPF にも引き継がれます。例の重要なポイントは次のとおりです。
- (または WPF を使用している
System.Windows.Timer.Timer
場合は同等の) を使用して、 を使用してキューからデータ項目をプルしますTryDequeue
。刻み頻度は、画面の更新が速く、UI スレッドの処理時間を支配するほど速くならないように、バランスのとれた値に設定してください。 - タスク/スレッドを使用して Web サイトからデータを取得し、 を使用してキューにロードします
Enqueue
。 - を使用して(この例には含めていません) を
CancellationTokenSource
介して操作をキャンセルし、によって提供されるを呼び出してポーリング間隔を駆動します。Cancel
WaitOne
WaitHandle
CancellationToken
やその他のマーシャリング手法を使用Control.Invoke
することは必ずしも悪いことではありませんが、万能薬であるとしばしば言われているわけでもありません。ここでは、この手法を使用する場合のいくつかの欠点を示します。
- UI とワーカー スレッドを緊密に結合します。
- ワーカー スレッドは、UI を更新する頻度を決定します。
- これは高価な操作です。
- ワーカー スレッドは、UI スレッドがメッセージを処理するまで待機する必要があるため、スループットが低下します。
UI スレッドが更新をポーリングする利点は次のとおりです。
- UI とワーカー スレッドはより疎結合です。実際、どちらも相手について何も知りません。
- UI スレッドは、更新を適用する頻度を独自に決定します。とにかく、これは本当にそうあるべきです。
- 高価なマーシャリング操作はありません。
- UI スレッドもワーカー スレッドも、他のスレッドによって実行が妨げられることはありません。両方のスレッドでスループットが向上します。
于 2013-11-01T14:41:39.077 に答える