2011-05-14 155 views
1

我的错误跨线程问题?

跨线程操作 无效:控制“MailTree”从比它 创建的线程以外的线程访问 。

我的代码 我的想法是,当SaveMail方法具有光洁度店1个MES再加入这个MES到列表视图。

private delegate int SaveMailDelegate(ImapX.Message mes); 

public int SaveMail(ImapX.Message mess) 
{ 
    if (!File.Exists("D:\\" + Username + "\\" + MailTree.SelectedNode.Text + "\\" + mes.MessageUid.ToString() + ".eml")) 
    { 
     mess.Process(); 
     mess.SaveAsEmlToFile("D:\\" + Username + "\\" + MailTree.SelectedNode.Text + "\\", mes.MessageUid.ToString()); //Store messages to a Location 

    } 
    // mes.MessageUid=mess.MessageUid; 
    return 1;    
} 
Mime EncodingMail(string NodeName,string focusitem) 
{ 
    Mime m = new Mime(); 
    m=Mime.Parse("D:\\" + Username+ "\\"+NodeName+"\\"+focusitem+".eml"); 
    return m; 
} 
private void AddMesToMailList() 
{ 
    ListViewItem item = new ListViewItem(); 
    Mime m = EncodingMail(MailTree.SelectedNode.Text, mes); 
    item.Text = mes.MessageUid.ToString(); 
    item.SubItems.Add(m.MainEntity.Subject); 
    ReturnMime(m); 
    if (mailfromname != null) 
     item.SubItems.Add(mailfromname); 
    else item.SubItems.Add(mailfrom); 
     item.SubItems.Add(m.MainEntity.Date.ToString()); 
    item.SubItems.Add(mailfrom); 
    MailList.Items.Add(item); 
} 
private void SaveMailDone(IAsyncResult iar) 
{ 
    SaveMailDelegate del = iar.AsyncState as SaveMailDelegate; 
    if (del != null) 
    { 
     int result = del.EndInvoke(iar); 
     AddMesToMailList();    
    } 
}  

private void MailTree_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e) 
{ 
    MailList.Items.Clear(); 
    for (int i = 0; i < client.Folders.Count; i++) 
    {       
     (ContextMenuListView.Items[1] as ToolStripMenuItem).DropDownItems[i].Click += new EventHandler(MainForm_Click); 
    } 
    if (MailTree.SelectedNode.Text == Username) 
    { 
     webBrowser1.Visible = false;//webBrowser1.DocumentText = "Hello Baby"; 
     AttachmentList.Visible = false; 
     groupBox1.Visible = false; 
    } 
    else 
    { 
     webBrowser1.Visible = true; 
     groupBox1.Visible = true; 

     try 
     { 
      messages = client.Folders[MailTree.SelectedNode.Text].Search("ALL", false); // Search mail in your choossen Folder 
      AmoutOfMail = messages.Count(); //Amout of Mail in this Folder           
      for (int i = 0; i < AmoutOfMail; i++) 
      { 
       mes=messages[i]; 
       SaveMailDelegate del = new SaveMailDelegate(this.SaveMail); 
       del.BeginInvoke(mes, new AsyncCallback(this.SaveMailDone), del);          
      } 
     } 
     catch (Exception) 
     { } 
    } 
} 
+0

搜索的BeginInvoke和Invoke – 2011-05-14 03:29:24

+0

我建议你使用'Path.Combine'来连接你的路径 – Flagbug 2011-05-14 09:15:12

回答

4

你不能直接从另一个线程访问控制,你必须调用它。

private delegate void ControlCallback(string s); 

public void CallControlMethod(string text) 
{ 
    if (control.InvokeRequired) 
    { 
     ControlCallback call = new ControlCallback((s) => 
     { 
      // do control stuff 
     }); 
     control.Invoke(call, new object[] { text }); 
    } 
    else 
    { 
     // do control stuff 
    } 
} 
1

我觉得AddMesToMailList()试图修改视图元素,但它是在一个错误的线程。

尝试这样的事情

void AddMesToMailList() 
{ 
    if (this.InvokeRequired) 
    { 
     this.BeginInvoke(new Action(AddMesToMailList)); 
     return; 
    } 

    // do stuff that original AddMesToMailList() did. 
} 

编辑: SaveMail是有点复杂,因为它有一个返回值,但你可以试试这个

public int SaveMail(ImapX.Message mess) 
{ 
    if(this.InvokeRequired) 
    { 
      return (int) this.Invoke(
        new Func<ImapX.Message, int>(m => SaveMail(mess))); 
    } 
    else 
    { 

     if (!File.Exists(@"D:\" + Username + "\\" + MailTree.SelectedNode.Text + "\\" + mes.MessageUid.ToString() + ".eml")) 
     { 
      mess.Process(); 
      mess.SaveAsEmlToFile(@"D:\" + Username + "\\" + MailTree.SelectedNode.Text + "\\", mes.MessageUid.ToString()); //Store messages to a Location 

     } 
     // mes.MessageUid=mess.MessageUid; 
     return 1; 

    } 



} 
+0

它仍然有同样的问题:( – giaosudau 2011-05-14 03:42:15

+0

也许它不是'AddMesToMailList() '但是当你得到这个异常时,它会告诉你哪个方法正在执行跨线程操作,并以上述相同的模式更改该方法。 – 2011-05-14 03:46:08

+0

跨线程操作无效:从其他线程访问的控件'MailTree'如果(!File.Exists(@“D:\”+ Username +“\\”+ MailTree.SelectedNode.Text +“\\”+ mes.MessageUid.ToString()+ “.eml”)) – giaosudau 2011-05-14 03:55:57

1

你不能访问上的UI不同于创建它的线程。从您的辅助线程(运行回调处理程序的线程)内部,您需要调用Form.BeginInvoke来注册将在UI线程上运行的方法。从这个方法,你可以更新你的UI控件