C# 如何在backgroundworker DoWork事件中启用/禁用按钮?
我有这个方法:C# 如何在backgroundworker DoWork事件中启用/禁用按钮?,c#,winforms,C#,Winforms,我有这个方法: private void CreateDriversList() { try { StreamWriter w = new StreamWriter(contentDirectory + "\\" + "Drivers.txt"); w.WriteLine("Module Name Display Name "
private void CreateDriversList()
{
try
{
StreamWriter w = new StreamWriter(contentDirectory + "\\" + "Drivers.txt");
w.WriteLine("Module Name Display Name " + " " + " Driver Type");
w.WriteLine("=========== ============ " + " " + " ===========");
System.Management.SelectQuery query = new System.Management.SelectQuery("Win32_SystemDriver");
System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher(query);
foreach (System.Management.ManagementObject ManageObject in searcher.Get())
{
w.WriteLine("{0,-22} {1,-75} {2}", ManageObject["Namedfgfdg"], ManageObject["DisplayName"], ManageObject["ServiceType"]);
driversListNumbers += 1;
}
w.Close();
Logger.Write("***** Drivers Text File Have Been Created *****");
}
catch(Exception err)
{
Logger.Write("There was an exception" + Environment.NewLine + err);
SendEmail.Enabled = true;
}
}
此方法是从DoWork事件调用的,当我运行程序时,会出现异常:
跨线程操作无效:从创建控件“SendEmail”的线程以外的线程访问控件“SendEmail”
System.InvalidOperationException was unhandled by user code
HResult=-2146233079
Message=Cross-thread operation not valid: Control 'SendEmail' accessed from a thread other than the thread it was created on.
Source=System.Windows.Forms
StackTrace:
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.Control.OnEnabledChanged(EventArgs e)
at System.Windows.Forms.ButtonBase.OnEnabledChanged(EventArgs e)
at System.Windows.Forms.Control.set_Enabled(Boolean value)
at Diagnostic_Tool_Blue_Screen.Form1.CreateDriversList() in d:\C-Sharp\Diagnostic Tool Blue Screen\Diagnostic Tool Blue Screen\Diagnostic Tool Blue Screen\Form1.cs:line 135
at Diagnostic_Tool_Blue_Screen.Form1.backgroundWorker1_DoWork(Object sender, DoWorkEventArgs e) in d:\C-Sharp\Diagnostic Tool Blue Screen\Diagnostic Tool Blue Screen\Diagnostic Tool Blue Screen\Form1.cs:line 177
at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e)
at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument)
InnerException:
工作线程不应接触UI。改用
BeginInvoke
:
SendEmail.BeginInvoke((Action)delegate() { SendEmail.Enabled = true; });
工作线程不应接触UI。改用
BeginInvoke
:
SendEmail.BeginInvoke((Action)delegate() { SendEmail.Enabled = true; });
你的选择是
调用和处理WorkerProcess的OnRunWorkerCompleted事件-
或者使用检查是否需要调用,然后在控件上使用调用-您的选项是
调用和处理WorkerProcess的OnRunWorkerCompleted事件-
或者检查是否需要调用,然后在控件上使用invoke-无法执行此操作。控件驻留在UI线程上,您试图从另一个线程修改控件,这是不可能的。您必须将结果返回到UI线程,并从那里对控件执行适当的操作。您不能这样做。控件驻留在UI线程上,您试图从另一个线程修改控件,这是不可能的。您必须将结果返回到UI线程,并从那里对控件采取适当的操作。使用Dispatcher,但下次使用google,很容易找到这个WPF或Windows窗体应用程序吗?从错误中看,它看起来像Windows窗体,因此您需要使用旧的InvokeRequired检查或使用BackgroundWork报告进度。使用Dispatcher,但下次使用google,很容易找到这个WPF或Windows窗体应用程序?从错误中看,它看起来像Windows窗体,因此您需要使用旧的InvokeRequired检查或使用BackgroundWork报告进度。rodrigo尝试了您的解决方案,但我现在收到一个错误:错误1无法将匿名方法转换为类型“System.Delegate”,因为它不是委托type@DanielVest
sendmail.BeginInvoke(新操作(()=>{sendmail.Enabled=true;}))
@DanielVest:是的,问题是,BeginInvoke
需要一个系统。委托
,奇怪的是,这不是委托类型。因此,您要么使用现有的委托类型(如操作
,请参阅我的更新答案或@KingKing注释),要么创建自己的委托类型。rodrigo尝试了您的解决方案,但我现在收到一个错误:错误1无法将匿名方法转换为类型“System.delegate”,因为它不是委托type@DanielVestsendmail.BeginInvoke(新操作(()=>{sendmail.Enabled=true;}));
@DanielVest:是的,问题是BeginInvoke
采用了系统。委托
,奇怪的是,这不是委托类型。所以要么使用已经存在的委托类型(例如操作
,请参阅我的更新答案或@KingKing注释)或者你自己创造。