0

Windows フォーム アプリケーションで UI の問題が発生しています。この問題に関してインターネット上に数え切れないほどの投稿があることは知っていますが、それでも適切な解決策を見つけることができませんでした.

私はこの方法を持っています:

private void AddContactTile(ContactTile c)
{
    if (mainPanel.InvokeRequired)
    {
        AddContactTileDelegate ctdelegate = new AddContactTileDelegate(AddContactTile);
        mainPanel.BeginInvoke(ctdelegate, c);
    }
    else
    {
        mainPanel.Controls.Add(c);
    }
}

そしてこの方法:

private void ChangeTileStatus(string userid)
{
    ContactTile tile = contactTiles.Find(x => x.Key == userid).Value;
    if (tile.statusLabel.InvokeRequired)
    {
        ChangeTileStatusDelegate ctsdelegate = new ChangeTileStatusDelegate(ChangeTileStatus);
        tile.statusLabel.BeginInvoke(ctsdelegate, userid);
    }
    else
    {
        if (contacts.ContainsKey(userid))
        {
            tile.statusLabel.Visible = contacts[userid].IsAvailable;
            tile.Refresh();
        }
    }
}

どちらもイベント ハンドラーで呼び出されます。イベントが同時に発生する可能性があるため、メソッドのstatusLabelコントロールで無効なクロススレッド操作メッセージを受け取ります。AddContactTile

これらのアクセスを適切に同期する方法を知っている人はいますか? ありがとう。

メソッドのコードAddContact:

public void AddContact(FacebookUser user)
{
    contacts[user.id].DisplayPictureAvailable += new EventHandler<UserEventArgs>(Contacts_DisplayPictureAvailable);
    contacts[user.id].StatusChanged += new EventHandler<UserEventArgs>(Contacts_StatusChanged);
    ContactTile c = new ContactTile(user.name, user.id) { Location = new Point(0, contactTiles.Count == 0 ? 0 : contactTiles.Last().Value.Bounds.Bottom) };
    contactTiles.Add(new KeyValuePair<string, ContactTile>(user.id, c));
    AddContactTile(c);
}

スタックトレース:

StackTrace  "   at System.Windows.Forms.Control.get_Handle()   at     
System.Windows.Forms.Control.UpdateChildZOrder(Control ctl)   at 
System.Windows.Forms.Control.WmCreate(Message& m)   at 
System.Windows.Forms.Control.WndProc(Message& m)   at 
System.Windows.Forms.Label.WndProc(Message& m)   at 
System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)"
4

2 に答える 2

3

ContactTileUIスレッド以外のスレッドで作成されAddContactTileますが、UIスレッドであると思われるスレッドに追加していmainPanel'sます。このルール「コントロールを作成したスレッド以外のスレッドからコントロールを呼び出すことは安全ではありません」ContactTileに従って、UI スレッドでもインスタンスを作成してみてください。

于 2013-06-13T22:09:15.493 に答える