跨线程问题:处理了无效的操作异常 [英] Cross threading problem: Invalid operationexception was handeled
问题描述
我正在制作一个从 txt 文件导入电子邮件并向他们发送消息的程序,但我遇到了一个问题,目前我正在使用线程发送邮件方法来防止程序停止响应,确切的问题标题是:
I am making a program that import emails from txt files and send a message to them , but i am facing a problem , currently i am using a thread for the sending mail method to prevent the program to stop responding , the exact problem title is:
Invalid operationexception was handeled
>>> Cross-thread operation not valid:
Control 'richTextBox1' accessed from a thread other than the thread it was created on.
这是代码
int success = 0;
int failed = 0;
int total = 0;
bool IsRunning;
List<string> list = new List<string>();
private void addmails()
{
string path = textBox2.Text;
foreach (string line in File.ReadAllLines(path))
{
list.Add(line);
}
IsRunning = true;
}
private void sendmails(object sender, DoWorkEventArgs e)
{
if (IsRunning == true)
{
if (checkBox1.Checked != true)
{
SmtpClient client = new SmtpClient(comboBox1.Text);
client.Credentials = new NetworkCredential(textBox6.Text, textBox7.Text);
MailMessage message = new MailMessage();
message.From = new MailAddress(textBox3.Text, textBox1.Text);
message.Subject = textBox4.Text;
//message.Body = richTextBox1.Text;
if (textBox5.Text != "")
{
message.Attachments.Add(new Attachment(textBox5.Text));
}
foreach (string eachmail in list)
{
if (IsRunning == true)
{
try
{
message.To.Add(eachmail);
client.Send(message);
listBox1.Items.Add("Successfully sent the message to : " + eachmail);
success++;
}
catch
{
listBox1.Items.Add("Failed to send the message to : " + eachmail);
failed++;
}
message.To.Clear();
total++;
Thread.Sleep(15);
label18.Text = total.ToString();
label19.Text = success.ToString();
label21.Text = failed.ToString();
}
else
{
break;
}
}
IsRunning = false;
button3.Text = "Send";
}
}
}
private void button3_Click(object sender, EventArgs e)
{
if (button3.Text == "Send")
{
tabControl1.SelectedTab = tabPage3;
button3.Text = "Stop";
addmails();
// IsRunning = true;
Thread t2 = new Thread(sendmails); // when using that thread i get a cross threading error
t2.Start();
}
else
{
IsRunning = false;
button3.Text = "Send";
MessageBox.Show("Sending Mails Operation has been terminated","Abort",MessageBoxButtons.OK,MessageBoxIcon.Information);
}
推荐答案
您正在使用从不同线程而不是创建它们的线程访问 UI 成员,您必须使用 Control.Invoke
每当您想从另一个线程访问 control
成员或方法时.因此,要使其发挥作用,您必须我真的不会这样做,而只是回答您的问题":
You are using accessing UI members from a different thread rather than the thread that they are created on, you have to use Control.Invoke
whenever you want to access control
members or method from another thread.
So, to get this to work you have to "I really would not do this but just answering your question":
if (IsRunning == true)
{
bool checkbox1Checked;
string textBox6Text;
string textBox7Text;
string textBox3Text;
string textBox1Text;
string textBox4Text;
string richTextBox1Text;
string textBox5Text;
MethodInvoker getValues = new MethodInvoker(delegate()
{
checkbox1Checked = checkbox1.Checked;
textBox6Text = textBox6.Text;
textBox7Text = textBox7.Text;
textBox3Text = textBox3.Text;
textBox1Text = textBox1.Text;
textBox4Text = textBox4.Text;
richTextBox1Text = richTextBox1.Text;
textBox5Text = textBox5.Text;
});
if (this.InvokeRequired)
{
this.Invoke(getValues);
}
else
{
getValues();
}
if (checkBox1Checked != true)
{
SmtpClient client = new SmtpClient(comboBox1Text);
client.Credentials = new NetworkCredential(textBox6Text, textBox7Text);
MailMessage message = new MailMessage();
message.From = new MailAddress(textBox3Text, textBox1Text);
message.Subject = textBox4Text;
//message.Body = richTextBox1Text;
if (textBox5Text != "")
{
message.Attachments.Add(new Attachment(textBox5Text));
}
foreach (string eachmail in list)
{
if (IsRunning == true)
{
try
{
message.To.Add(eachmail);
client.Send(message);
MethodInvoker addToListBox = new MethodInvoker(delegate()
{
listBox1.Items.Add("Successfully sent the message to : " + eachmail);
});
if (listBox1.InvokeRequired)
{
listBox1.Invoke(addToListBox);
}
else
{
addToListBox();
}
success++;
}
catch
{
MethodInvoker addToListBox = new MethodInvoker(delegate()
{
listBox1.Items.Add("Failed to send the message to : " + eachmail);
});
if (listBox1.InvokeRequired)
{
listBox1.Invoke(addToListBox);
}
else
{
addToListBox();
}
failed++;
}
message.To.Clear();
total++;
Thread.Sleep(15);
MethodInvoker updateSatatus = new MethodInvoker(delegate()
{
label18.Text = total.ToString();
label19.Text = success.ToString();
label21.Text = failed.ToString();
});
if (this.InvokeRequired)
{
this.Invoke(updateSatatus);
}
else
{
updateSatatus();
}
}
else
{
break;
}
}
IsRunning = false;
if (button3.InvokeRequired)
{
button3.Invoke(new MethodInvoker(delegate() { button3.Text = "Send"; } ));
}
else
{
button3.Text = "Send";
}
}
}
这篇关于跨线程问题:处理了无效的操作异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!