在给客户做的一个程序中附带一个聊天程序, 若先在主窗口创建聊天窗口, 一切正常, 但消息触发创建的窗口, 主程序在调用时, 出现跨线程控件调用错误, 怎么处理, 谢谢拉!!!!!

解决方案 »

  1.   

    // 源代码1.ClientMessageManagerusing System;
    using System.ComponentModel;
    namespace ESAPP.Net
    {
        public delegate void EmptyMethod();    public class ClientMessageManager
        {
            IAppServer server;
            AppEventRepeater repeater;
            ChatRoom chatRoom;        public ClientMessageManager(IAppServer server, AppEventRepeater repeater)
            {
                this.server = server;
                this.repeater = repeater;
                
                repeater.MessageReceived += new MessageEventHandler(repeater_MessageReceived);           
            }        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                ChatRoom room = CreateChatRoom();
                room.Show();
                room.WindowState = System.Windows.Forms.FormWindowState.Normal;
                room.BringToFront();
            }        
            public ChatRoom CreateChatRoom()
            {          
                if (chatRoom == null)
                {
                    chatRoom = new ChatRoom(repeater.UserID, repeater.UserName, server);
                    chatRoom.Disposed += new EventHandler(chatRoom_Disposed);
                }
                return chatRoom; 
            }        void chatRoom_Disposed(object sender, EventArgs e)
            {
                this.chatRoom = null;
                server.RemoveRepeater(this.repeater);
            }
            public void ShowChatRoom()
            {
                ChatRoom room = CreateChatRoom();            if (room.InvokeRequired)
                {
                    EmptyMethod m = new EmptyMethod(room.Show);
                    //room.Invoke(m);  用此方法调用, 程序没有响应
                    m.Invoke();  // 用此方法调用, 出现跨线程调用控件错误
                                   EmptyMethod m2 = new EmptyMethod(room.BringToFront);
                    ////room.Invoke(m2); 
                    room.Invoke(m2);
                }
                else
                {
                    room.Show();
                    room.WindowState = System.Windows.Forms.FormWindowState.Normal;
                    room.BringToFront();
                }            
            }
            #region 接收/处理消息
            void repeater_MessageReceived(object sender, MessageEventArgs e)
            {
                if (e.Message.Type == MessageType.Chat)
                {
                    SendMsgToChatRoom(e);
                }
            }              void SendMsgToChatRoom( MessageEventArgs e)
            {
                if (chatRoom == null)
                {
                    this.CreateChatRoom();
                    chatRoom.Show();                chatRoom.WindowState = System.Windows.Forms.FormWindowState.Minimized;
                }            MessageEventHandler handler = new MessageEventHandler(chatRoom.OnMessageReceived);
                handler.Invoke(null, e);
            }        #endregion
        }
    }
      

  2.   

    源代码2.  ChatRoom, 没有问题using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;namespace ESAPP.Net
    {
        public partial class ChatRoom : Form
        {
            private Icon m_Icon1;
            private Icon m_Icon2;
            private bool m_bFlag;    
            private IAppServer server;
          
            string userID;       
            string userName;        delegate void SetTextCallback(string text);
                    
            public ChatRoom(string userID, string userName, IAppServer server)
            {            InitializeComponent();            this.userID = userID;
                this.userName = userName;            this.listBox1.Items.Add("所有人");            this.server = server;
                try
                {
                    server.UserAdded += new AppUserEventHanlder(server_UserAdded);
                    server.UserRemoved += new AppUserEventHanlder(server_UserRemoved);
                    server.UserInterrupted += new AppUserEventHanlder(server_UserInterrupted);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.Fail(ex.ToString());
                }            ErrorList errors = new ErrorList();            SimpleUserInfoList infos =  server.GetSimpleUserInfos(errors);
                if (errors.Count == 0)
                {
                    foreach (SimpleUserInfo info in infos)
                    {
                        if (info.UserID != userID)
                        {
                            this.listBox1.Items.Add(info);
                        }
                    }
                }
                else
                {
                    MessageBox.Show("错误: "  + errors.ToString(), "获取用户列表", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
               
                m_bFlag = true;            //导入图标文件
                try
                {
                    m_Icon1 = new Icon("Icon1.ico");
                    m_Icon2 = new Icon("Icon2.ico");
                }
                catch (Exception e)
                {
                    MessageBox.Show("错误: " + e.Message, "即时通信");
                }
            }              
            void server_UserInterrupted(object sender, AppUserEventArgs e)
            {
                if (e.UserID != userID)
                {
                    this.SetUserRemoved(e.UserID);
                }
                
            }        void server_UserRemoved(object sender, AppUserEventArgs e)
            {
                if (e.UserID != userID)
                {
                    this.SetUserRemoved(e.UserID);
                }
            }        void server_UserAdded(object sender, AppUserEventArgs e)
            {
                if (e.UserID != userID)
                {
                    this.SetUserAdded(e.UserID);
                }
            }
            public void OnMessageReceived(object sender, MessageEventArgs e)
            {
                if (e.Message.Type != MessageType.Chat)
                {
                    return;
                }            if (this.isShown == false)
                {
                    this.WindowState = System.Windows.Forms.FormWindowState.Minimized;
                    this.Show();
                }            if (this.WindowState == FormWindowState.Minimized)
                {                
                    try
                    {
                        timer1.Start();
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.Fail(ex.ToString());
                    }
                }
                this.SetText(string.Format("{0} 对你说: {1}" , e.Message.SenderName , e.Message.Message));        }
            private void SetText(string text)
            {
                if (this.txtMessage.InvokeRequired)
                {
                    SetTextCallback d = new SetTextCallback(SetText);
                    this.Invoke(d, new object[] { text });
                }
                else
                {
                    this.txtMessage.Text += text + Environment.NewLine;
                }
            }
            private void SetUserAdded(string userID)
            {
                if (this.listBox1.InvokeRequired)
                {
                    SetTextCallback d = new SetTextCallback(SetUserAdded);
                    this.Invoke(d, new object[] { userID });
                }
                else
                {
                    this.listBox1.OnUserAdded(userID);
                }
            }        private void SetUserRemoved(string userID)
            {
                if (this.listBox1.InvokeRequired)
                {
                    SetTextCallback d = new SetTextCallback(SetUserRemoved);
                    this.Invoke(d, new object[] { userID });
                }
                else
                {
                    this.listBox1.OnUserRemoved(userID);
                }
            }
            bool isShown = false;
            protected override void OnShown(EventArgs e)
            {
                isShown = true;
                base.OnShown(e);
            }        private void ChatRoom_Resize(object sender, EventArgs e)
            {
                if (this.WindowState == FormWindowState.Minimized)
                {
                    this.Hide();
                    this.notifyIcon1.Icon = m_Icon1;
                    m_bFlag = true;
                }
                else
                {
                    this.timer1.Stop();
                    this.notifyIcon1.Icon = m_Icon1;
                    m_bFlag = true;
                }
            }        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
            {
                if (this.Visible)
                {
                    return;
                }            timer1.Stop();
                notifyIcon1.Icon = m_Icon1;
                m_bFlag = true;            this.Visible = true;
                this.WindowState = FormWindowState.Normal;
            }        private void timer1_Tick(object sender, EventArgs e)
            {
                if (m_Icon1 != null && m_Icon2 != null) //如果两个图标文件都被正确载入
                {
                    if (m_bFlag == true)
                    {
                        this.notifyIcon1.Icon = m_Icon2;
                        m_bFlag = false;
                    }
                    else
                    {
                        this.notifyIcon1.Icon = m_Icon1;
                        m_bFlag = true;
                    }
                }
            }        private void btnSend_Click(object sender, EventArgs e)
            {
                string msg = txtNewMsg.Text.Trim();            if (msg == "")
                {
                    return;
                }            string receiverID = null;
                if (listBox1.SelectedIndex > 0)
                {
                    receiverID = (this.listBox1.SelectedItem as SimpleUserInfo).UserID;
                }            AppMessage m = new AppMessage();
                m.Message = msg;
                m.SenderID = userID;
                m.SenderName = userName;
                m.ReceiverID = receiverID;            server.MsgService.SendMessage(m);
                
            }        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
                int index = listBox1.SelectedIndex;            string name = (index == 0) ? "所有人" : (this.listBox1.SelectedItem as SimpleUserInfo).UserName;
                this.txtReceiver.Text = name;
            }
           
        }
    }
      

  3.   

    错误出现在: 
    public void ShowChatRoom()
            {
                ChatRoom room = CreateChatRoom();            if (room.InvokeRequired)
                {
                    EmptyMethod m = new EmptyMethod(room.Show);
                    //room.Invoke(m);  用此方法调用, 程序没有响应
                    m.Invoke();  // 用此方法调用, 出现跨线程调用控件错误
                                   EmptyMethod m2 = new EmptyMethod(room.BringToFront);
                    ////room.Invoke(m2); 
                    room.Invoke(m2);
                }
                else
                {
                    room.Show();
                    room.WindowState = System.Windows.Forms.FormWindowState.Normal;
                    room.BringToFront();
                }            
            }怎么解决, 谢谢,谢谢, 再谢谢!!!!
      

  4.   

    错误出现在: 
    public void ShowChatRoom()
            {
                ChatRoom room = CreateChatRoom();            if (room.InvokeRequired)
                {
                    EmptyMethod m = new EmptyMethod(room.Show);
                    //room.Invoke(m);  用此方法调用, 程序没有响应
                    m.Invoke();  // 用此方法调用, 出现跨线程调用控件错误
                                   EmptyMethod m2 = new EmptyMethod(room.BringToFront);
                    ////room.Invoke(m2); 
                    room.Invoke(m2);
                }
                else
                {
                    room.Show();
                    room.WindowState = System.Windows.Forms.FormWindowState.Normal;
                    room.BringToFront();
                }            
            }怎么解决, 谢谢,谢谢, 再谢谢!!!!
    尝试修改为:public void ShowChatRoom()
            {
                ChatRoom room = CreateChatRoom();            if (room.InvokeRequired)
                {
                    EmptyMethod m = new EmptyMethod(room.Show);
                    //room.Invoke(m);  用此方法调用, 程序没有响应
                    this.Invoke();  // 用此方法调用, 出现跨线程调用控件错误
                                   EmptyMethod m2 = new EmptyMethod(room.BringToFront);
                    ////room.Invoke(m2); 
                    this.Invoke(m2);
                }
                else
                {
                    room.Show();
                    room.WindowState = System.Windows.Forms.FormWindowState.Normal;
                    room.BringToFront();
                }            
            }
      

  5.   

    尝试修改为:public void ShowChatRoom()
            {
                ChatRoom room = CreateChatRoom();            if (room.InvokeRequired)
                {
                    EmptyMethod m = new EmptyMethod(room.Show);
                    //room.Invoke(m);  用此方法调用, 程序没有响应
                    this.Invoke(m);  // 用此方法调用, 出现跨线程调用控件错误
                                   EmptyMethod m2 = new EmptyMethod(room.BringToFront);
                    ////room.Invoke(m2); 
                    this.Invoke(m2);
                }
                else
                {
                    room.Show();
                    room.WindowState = System.Windows.Forms.FormWindowState.Normal;
                    room.BringToFront();
                }            
            }
      

  6.   

    wuyazhe(接单:wince应用软件/上位机(串口,usb)软件) 
    由于: ShowChatRoom方法在类ClientMessageManager, 这个类负责接受消息并处理的, 不是一个Windows控件, 不能调用this.Invoke()我试试将从Control中继承, 调用this.Invoke(m)
      

  7.   

    只要你找到任意一个在主线程中创建的Control就可以用它的Invoke(m);如果找不到,人为生成一个也行,把它设置成Public Static,无论在哪里都能访问到,但关键一定要在主线程上生成它的实例.
      

  8.   

    你这里边还有一个问题:生成ChatRoom也需要在主线程上,也就是说 CreateChatRoom()也要在主线程上运行,这样改:public void ShowChatRoom()
    {//myControl: 是一个主线程上生成的Control
    /在这里实际上不用判断 if (room.InvokeRequired)
    myControl.Invoke(new EmptyMethod(CreateChatRoom));}
    //把Show(); 和 BringToFront(); 也加到这里边去.
    public ChatRoom CreateChatRoom()
     {          
                if (chatRoom == null)
                {
                    chatRoom = new ChatRoom(repeater.UserID, repeater.UserName, server);
                    chatRoom.Disposed += new EventHandler(chatRoom_Disposed);
                   chatRoom.Show(); 
                    chatRoom.BringToFront();
                }
                return chatRoom; 
    }
      

  9.   

    那就不要用show了。就这样
    ChatRoom room = CreateChatRoom();
    room.Show();
    Application.Run(room);
      

  10.   

    if (this.InvokeRequired)
                {
                     EmptyMethod m = new EmptyMethod(room.Show);
                    delegate void MessageReceiveHandler();
                    MessageReceiveHandler handler = new MessageReceiveHandler(m);
                    Invoke(handler, sender, e);
                }
      

  11.   

    把需要的资源作成全局的 就可以了或者用REF把对象传进去啊
    这么简单的问题