アーキテクチャの観点から:
アプリケーションのメッセージキューのデカップルビット。 Windows Formsアプリケーションでは、Windowsが作成して管理するメッセージキューに依存することができます。 Google for PostMessage/GetMessageなど。これは一般的に「メッセージパッシング」と呼ばれます。あなたのアプリの
典型的なArcitecture
- 一部はキューに要求
- のアプリのいくつかの他の部分はキューから要求を「プル」との結果を書き込み「プッシュ」 2番目のキュー。
- 最初の部分は、2番目の「結果」キューから要求を「プル」してユーザーに表示できます。
だから、次のようになります。
アプリケーション - >要求QUEUE - >処理エンジン - > RESULTSのQUEUE - >アプリケーション
処理エンジンは同じアプリで可能性があり、同じスレッドまたは異なるスレッド/プロセス(または別のマシン)で実行されます。
単純なキューを使用することができます(たとえば、ロックを使用してアクセスする場合はQueue<string>()
)、複雑性や複雑性/機能性の高いキューを増やすことができます。素朴な戦略や他のソリューションとの
問題...考えるべき事:
- 古いものがまだ完了していない間、あなたは新しい要求を行う場合はどうなりますか?
- エラーが発生した場合はどうなりますか?エラーがインラインで欲しいですか?エラーのために別のキューを使用できますか?
- 再試行しますか?
- メッセージが失われた場合はどうなりますか? (つまり、リクエストはプッシュされましたが、応答はありません...)トランザクションキュー等
サンプルコード
object oLock = new object();
Queue<string> requests = new Queue<string>();
Queue<string> responses = new Queue<string>();
Thread mThread;
AutoResetEvent mEvent = new AutoResetEvent(false);
public Form1()
{
InitializeComponent();
mThread = new Thread(ProcessingEngine);
mThread.IsBackground = true;
mThread.Start();
}
private void ProcessingEngine()
{
string result;
string request = null;
while (true)
{
try
{
mEvent.WaitOne();
lock (oLock)
{
request = requests.Dequeue();
}
var wc = new WebClient();
result = wc.DownloadString(request);
lock (oLock)
{
responses.Enqueue(result);
}
}
catch (Exception ex)
{
lock (oLock)
{
responses.Enqueue(ex.ToString());
}
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
lock (oLock)
{
//Stick in a new request
requests.Enqueue("http://yahoo.com");
//Allow thread to start work
mEvent.Set();
//Check if a response has arrived
if (responses.Any())
{
var result = responses.Dequeue();
listBox1.Items.Add(result.Substring(1,200));
}
}
}
}
-1があります。これによりスケーラビリティが損なわれ、スレッドが一時的にタイムアウトすると、タイムアウトが発生するまでUIがブロックされますが、これは悪いことです。 Threading.Timerを使用すると、別のスレッドでの実行が可能になり、次にUIの更新だけをメインスレッド(ウィンドウ上のInvokeメソッド)に戻して呼び出すことができます。 – TomTom
どうしてですか? RunWorkerAsyncが目立つ時間にブロックされているのをまだ見ていないのですが、Threading.Timer.Tickから直接UIを更新することはできず、Timerで 'Invoke'を使用すると' RunWorkerCompleted'から更新するのと全く同じ結果になります。 DoWorkは独自のスレッドで実行されるので、なぜUIがブロックされると思うか説明してください。 – MagnatLU
Comp投票、このようにすることに何も問題はありません。ブロッキングは一切発生せず、ビジー状態のBGWを実行しようとすると例外が発生します。どちらの種類のタイマーでも。少なくとも、スレッドが多すぎることに対するOPの懸念が緩和されます。 –