交叉线程问题
本文关键字:问题 线程 | 更新日期: 2023-09-27 17:56:38
我的错误
跨线程操作不 有效:控制访问的"邮件树" 从线程以外的线程 它 是在上创建的。
用我的代码我的想法是当 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)
{ }
}
}
不能直接从另一个线程访问控件,必须调用它。
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
}
}
您无法
在与创建 UI 时不同的线程上访问 UI。在辅助线程(运行回调处理程序的线程)内部,需要调用 Form.BeginInvoke 来注册将在 UI 线程上运行的方法。通过该方法,您可以更新 UI 控件
我认为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;
}
}