3

通常の UI スレッドとバックグラウンド ワーカーを備えたシンプルなアプリがあります。バックグラウンド ワーカーでは、LinkLabels を動的に作成して FlowLayoutPanel に配置する必要があります。これを行うには、LinkLabel の親を FlowLayoutPanel に設定する必要があります。

これは私が現在持っているコードのスニペットですが、「l.Parent = panel;」という行で悪名高い「クロススレッド操作が無効です」というメッセージが表示されます。

私はマルチスレッド操作にかなり慣れていませんが、正しく呼び出したと思っていましたが、明らかにそうではありませんでした。助言がありますか?

LinkLabel l = new LinkLabel();
if (rssFeedPanel.InvokeRequired) {
    FlowLayoutPanel panel = null;
    rssFeedPanel.Invoke(new MethodInvoker(delegate { panel = rssFeedPanel; }));
    l.Parent = panel;
}
else
    l.Parent = rssFeedPanel;
4

2 に答える 2

3

ロジックを 1 つのメソッドに入れ、まず InvokeRequired かどうかを確認してから、Invoke 内でそのメソッドを呼び出し、それ以外の場合は直接呼び出すことをお勧めします。

if (rssFeedPanel.InvokeRequired) {
    rssFeedPanel.Invoke(new MethodInvoker(delegate 
    { 
        AddLabel();
    }));
}
else AddLabel();

AddLabel メソッドにロジックを入れます。

private void AddLabel()
{
    LinkLabel l = new LinkLabel();
    l.Parent = rssFeedPanel;
}
于 2012-01-07T19:39:44.920 に答える
3

Parent他のスレッドで実際にプロパティを設定する必要があります。

LinkLabel l = new LinkLabel();
if (rssFeedPanel.InvokeRequired) {
    rssFeedPanel.Invoke(new MethodInvoker(delegate {
        l.Parent = rssFeedPanel;
    }));
}
else
    l.Parent = rssFeedPanel;

一般に、UI コントロールのメンバーへのアクセスを含むほぼすべての操作は、UI スレッドからのみ実行できます。いくつかの明らかな例外は、、、、InvokeおよびクラスInvokeRequiredBeginInvokeメソッドの一部です。BackgroundWorker

このケースを希望する場合は、BeginInvokeの代わりに使用することもできますInvoke

于 2012-01-07T19:34:21.943 に答える