2010-11-18 11 views
2

まずはスプラッシュスクリーンではなく、私が欲しいものを...クリアするだけです... ok ...問題の説明に行きます:複雑なマルチスレッドインターフェイス

フォームはN個のスレッドを起動します(私はどれくらいの数のユーザーが選択しなければならないかわかりません)...各スレッドにオブジェクトがあり、いくつかの瞬間にオブジェクトがイベントを発生させて変更を通知します...フォームが必要です各スレッドがイベントが送信しているメッセージを「レポート」する...

私の問題は:スレッドは完全にフォームを作成します...しかし、どこにも表示されません。画面が消えて...消えてしまった。どのように私はその望ましくない "処分"を避けることができますか?

答えて

1

スレッドでフォームを作成すると、スレッドが完了するとフォームが消えます。フォームが存続するよりも長く存続させるには、スレッドを有効にしておくか、アプリケーションのメインスレッドでフォームを作成する必要があります。後者が好ましいだろう。それぞれのオブジェクトが対応するフォームのイベントリスナーに接続するようにし、フォームを更新するときは必要に応じてInvokeまたはBeginInvokeを使用してください。

簡単な例:まず

ワーカー: クラスワーカー {公共のイベントのEventHandler SomethingHappened。

protected void OnSomethingHappened(EventArgs e) 
    { 
     var evnt = SomethingHappened; 
     if (evnt != null) 
     { 
      evnt(this, e); 
     } 
    } 
    public void Work() 
    { 
     // do lots of work, occasionally calling 
     // OnSomethingHappened 
    } 
} 

その後、我々はSomethingHappenedイベントのイベントハンドラを持つ形で:

Worker w = new Worker(); 
ProgressForm f = new ProgressForm; 
w.SomethingHappened += f.SomethingHappenedHandler; 
f.Show(); 
Thread t = new Thread(w.Work); 
t.Start(); 

免責事項:

public void SomethingHappenedHandler(object sender, EventArgs e) 
{ 
    if (this.InvokeRequired) 
    { 
     this.Invoke(new Action(() => SomethingHappenedHandler(sender, e))); 
     return; 
    } 

    // update gui here 
} 

そして、それは本当にすべて一緒にそれを配線するだけです:このサンプルはすばやく投げ込まれ、ややテストされていません(電車に座って降りていく)。

+0

どうすればいい?スレッドからメインフォームを起動し、新しいフォームを作成しますか? – Leonardo

+0

@レオナルド:更新された答えを見てください。 –

+0

私はそれほど気に入らなかったが、アイデアを使った。 Tks! – Leonardo

2

あなたのスレッドは、どちらか

  • ます(ないが)どちらをしました
  • たり、自分のMessagePump(Application.Run)を実行

を適切InvokeRequired +呼び出しロジックを使用する必要がありますか?

1

Formは、メッセージループを持つスレッドでホストする必要があります。メッセージループは、Application.RunまたはForm.ShowDialogのいずれかを呼び出して作成できます。しかし、あなたが本当に良い理由がない限り、私はWindowsメッセージループを持つ複数のスレッドを避けるでしょう。

また、N個のスレッドを作成することも避けます。操作ごとに1つのスレッドを作成する以外に、N個の操作を並列化するより良い方法があります。 2つだけを指定するには、1)ThreadPoolに作業項目をキューイングするか、または2)Taskクラスでタスク並列ライブラリを使用します。 N個のスレッドを作成する際の問題は、各スレッドが一定量のリソースを消費することです。スレッドが増えると、より多くのリソースが消費され、より多くのコンテキスト切り替えが行われることを意味します。マルチスレッドの世界では、それ以上のものが常に良いとは限りません。

+0

imは.Net 3.5で作業しません... sob ...そして、ユーザーが同時にいくつのスレッドが同時に動作しているかを定義する必要があります.... – Leonardo

+0

@レオナルド:マイクロソフトはタスク並列ライブラリのバックポートを持っています。これにはReactive Extensionsのダウンロードで.NET 3.5で利用できる 'Task'クラスが含まれています。それのためだけにGoogle。 –

+1

@レオナルド:ユーザーがスレッド数を指定するのがさらに悪いです。最適なスレッド数は、エンドユーザーが開発者よりも一貫して優れた判断を下す方法はありません。 –