2008年4月5日土曜日

バックグランドスレッド

uGReaderでフィードの受信処理等の時間のかかる処理中に、ui操作が止まらないように、メインスレッドの裏で動く別スレッドを作って処理をさせてます

普通は受信処理を非同期に行いたいならHttpWebRequestクラスなどでBeginGetResponseメソッドを使用すると思います。しかし以前にuGNoteで画像ファイルをダウンロードする為にHttpWebRequestを同時たくさん実行したら、多くのリクエストが失敗する事がありました。
それ以来BeginGetResponseを使用せずに、別スレッド内でGetResponseをするようにしてます。更に別スレッドの生成数も制御して、同時に複数のHttpリクエスト処理を実行しないようにキュー処理するロジックにしました

メインスレッドから受信処理が必要な場合は、リクエストをキューに書き込んで受信後の処理をコールバック関数で行う

バックグランドスレッドはリクエストキューに従って受信処理を実行して、終了時にコールバック関数をメインスレッドでInvokeを使って実行させる

バックグランドスレッドはこんな感じ

private void BackgroundThread()
{
BackgroundAbort = false;
while (!BackgroundAbort)
{
AsyncGetObject obj = m_threadque.get();
if (obj != null)
{
XmlDocument xml = mfeed.GetXmlFeed(obj.url);
this.Invoke((AsyncGetDelegate)obj.callback, xml);
}
else
{
autoEvent.WaitOne();
}
}
}

とりあえず、受信要求を順番に非同期処理ができましたが、なんか泥臭い
こういうのはThreadPoolを使って簡単に記述することができるような気がしてます
ただし、同時に複数の受信処理はしたくないので、そのへんの制御をどうやるのか?勉強して組み込みできたらいいなと思ってます

ThreadPool処理とListViewの置き換えができたらリリース版にするつもりです

その前に、要望にあった画像を表示しないオプション追加版を公開します

0 件のコメント: