2011-05-14 113 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控件