如何将变量传递给任务工厂操作

本文关键字:任务 工厂 操作 变量 | 更新日期: 2023-09-27 18:04:35

我喜欢使用任务发送邮件。下面是我调用SendMail方法的代码:

Task.Factory.StartNew(() => SendMail(toTextBox.Text,
                                     subjectTextbox.Text,
                                     BodyEditor.ContentHtml,
                                     filenames.ToArray(),
                                     ccTextBox.Text,
                                     bccTextBox.Text));

问题是:我不能像这样传递UI信息(文本框等),因为对象由另一个线程拥有。

错误消息:调用线程不能访问这个对象,因为它被另一个线程拥有。

我应该如何将这些参数传递给我的动作?

如何将变量传递给任务工厂操作

您是否已经在 UI线程中了?如果是这样,您只需要首先提取属性,这样当调用lambda表达式时,您就已经执行了属性访问。

例如:

string recipient = toTextBox.Text;
string subject = subjectTextBox.Text;
string html = BodyEditor.ContentHtml;
string cc = ccTextBox.Text;
string bcc = bcTextBox.Text();
Task.Factory.StartNew(() => SendMail(recipient,
                                     subject,
                                     html,
                                     filenames.ToArray(),
                                     cc,
                                     bcc));

变量将被lambda表达式捕获—基本上编译器将为您生成一个额外的类,该类将信息隐藏起来,因此当lambda表达式求值时,它仍然可用。

如果这段代码在UI线程中执行而不是,那么你基本上需要将整个东西包装在另一个动作中,以便在UI线程中执行它:

Action action = () {
    string recipient = toTextBox.Text;
    string subject = subjectTextBox.Text;
    string html = BodyEditor.ContentHtml;
    string cc = ccTextBox.Text;
    string bcc = bcTextBox.Text();
    Task.Factory.StartNew(() => SendMail(recipient,
                                         subject,
                                         html,
                                         filenames.ToArray(),
                                         cc,
                                         bcc));
};
// Or Dispatcher.BeginInvoke(action); for WPF/Silverlight.
BeginInvoke(action);

声明包含UI变量值的新变量,并将其传递给任务

string to = toTextBox.Text;
string subject = subjectTextBox.Text;
string cc = ccTextBox.Text;
string bcc = bccTextBox.Text;
string files = filenames.ToArray();
Task.Factory.StartNew(() => SendMail(to, subject,BodyEditor.ContentHtml, files, cc, bcc));

如果您不直接使用对象及其属性,而是将您希望使用的值复制到变量中,然后将它们传递给变量,那么它会工作吗?