private void btnNext_Click(object sender, System.EventArgs e)
{
if (availableUpdate > 0)
{
Thread threadDown=new Thread(new ThreadStart(DownUpdateFile));
threadDown.IsBackground = true;
threadDown.Start();
}
else
{
MessageBox.Show("没有可用的更新!自动程序将在你点击确定后自动退出!","自动更新",MessageBoxButtons.OK,MessageBoxIcon.Information);
Application.Exit();
//return;
}
}
private void DownUpdateFile()
{
this.Cursor = Cursors.WaitCursor;
mainAppExe = updaterXmlFiles.GetNodeValue("//EntryPoint");
Process [] allProcess = Process.GetProcesses();
foreach(Process p in allProcess)
{
if (p.ProcessName.ToLower() + ".exe" == mainAppExe.ToLower() )
{
for(int i=0;i<p.Threads.Count;i++)
p.Threads[i].Dispose();
p.Kill();
isRun = true;
//break;
}
}
在程序运行至:this.Cursor = Cursors.WaitCursor;
的时候,爆错,提示:
未处理 System.InvalidOperationException
Message="线程间操作无效: 从不是创建控件“FrmUpdate”的线程访问它。"
Source="System.Windows.Forms"
StackTrace:
在 System.Windows.Forms.Control.get_Handle()
在 System.Windows.Forms.Control.set_Cursor(Cursor value)
在 AutoUpdate.FrmUpdate.DownUpdateFile() 位置 D:\development\c#autoupdate\AutoUpdate\FrmUpdate.cs:行号 445
在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()
这一个自动更新的程序,可是应该怎么解决了,新手提问!!!
6 个解决方案
#1
你的DownUpdateFile()既然是获取升级文件的
就不要和UI交互了
去掉所有与界面有关的代码,因为UI有一个高优先级线程了,你开的线程再去惹UI线程管的资源
会发生资源争用
线程之间用纯数据交互
就不要和UI交互了
去掉所有与界面有关的代码,因为UI有一个高优先级线程了,你开的线程再去惹UI线程管的资源
会发生资源争用
线程之间用纯数据交互
#2
楼上正解
把你的代码做如下修改:
应该没问题的了
第二种解决办法:
一定要使用鼠标等待效果的话,在UI线程设置成等待效果,然后用AutoResetEvent和WaitHandle控制线程的同步,后台线程运行完再设置为正常状态,不废话了
把你的代码做如下修改:
private void btnNext_Click(object sender, System.EventArgs e)
{
if (availableUpdate > 0)
{
Thread threadDown=new Thread(new ParameterizedThreadStart(DownUpdateFile));//改用带参委托
threadDown.IsBackground = true;
threadDown.Start(this);//传入当前对象
}
else
{
MessageBox.Show("没有可用的更新!自动程序将在你点击确定后自动退出!","自动更新",MessageBoxButtons.OK,MessageBoxIcon.Information);
Application.Exit();
//return;
}
}
private void DownUpdateFile(Object obj)//设置一个Object参数
{
Control form=(Control)obj //强制转换为Control
form.Cursor = Cursors.WaitCursor;
mainAppExe = updaterXmlFiles.GetNodeValue("//EntryPoint");
Process [] allProcess = Process.GetProcesses();
foreach(Process p in allProcess)
{
if (p.ProcessName.ToLower() + ".exe" == mainAppExe.ToLower() )
{
for(int i=0;i<p.Threads.Count;i++)
p.Threads[i].Dispose();
p.Kill();
isRun = true;
//break;
}
}
应该没问题的了
第二种解决办法:
一定要使用鼠标等待效果的话,在UI线程设置成等待效果,然后用AutoResetEvent和WaitHandle控制线程的同步,后台线程运行完再设置为正常状态,不废话了
#3
嗯,那就是我的思路全错了
要改,后面的函数得全改
各位大哥,我初学,这一下子,完了,又得全新去看,而且还不知道怎么写了.
不过,非常感谢楼上二位的解答
特别感谢linq_chen ,因为我是新手,理论更难懂,有代码,有注释,让我受益非浅!!!
继续修改这个程序,希望能完善!
要改,后面的函数得全改
各位大哥,我初学,这一下子,完了,又得全新去看,而且还不知道怎么写了.
不过,非常感谢楼上二位的解答
特别感谢linq_chen ,因为我是新手,理论更难懂,有代码,有注释,让我受益非浅!!!
继续修改这个程序,希望能完善!
#4
在构造函数上加上这句话也可以
CheckForIllegalCrossThreadCalls = false;
CheckForIllegalCrossThreadCalls = false;
#5
在构造函数上加上这句话也可以
CheckForIllegalCrossThreadCalls = false;
才是正解
CheckForIllegalCrossThreadCalls = false;
才是正解
#6
谢谢楼主了
#1
你的DownUpdateFile()既然是获取升级文件的
就不要和UI交互了
去掉所有与界面有关的代码,因为UI有一个高优先级线程了,你开的线程再去惹UI线程管的资源
会发生资源争用
线程之间用纯数据交互
就不要和UI交互了
去掉所有与界面有关的代码,因为UI有一个高优先级线程了,你开的线程再去惹UI线程管的资源
会发生资源争用
线程之间用纯数据交互
#2
楼上正解
把你的代码做如下修改:
应该没问题的了
第二种解决办法:
一定要使用鼠标等待效果的话,在UI线程设置成等待效果,然后用AutoResetEvent和WaitHandle控制线程的同步,后台线程运行完再设置为正常状态,不废话了
把你的代码做如下修改:
private void btnNext_Click(object sender, System.EventArgs e)
{
if (availableUpdate > 0)
{
Thread threadDown=new Thread(new ParameterizedThreadStart(DownUpdateFile));//改用带参委托
threadDown.IsBackground = true;
threadDown.Start(this);//传入当前对象
}
else
{
MessageBox.Show("没有可用的更新!自动程序将在你点击确定后自动退出!","自动更新",MessageBoxButtons.OK,MessageBoxIcon.Information);
Application.Exit();
//return;
}
}
private void DownUpdateFile(Object obj)//设置一个Object参数
{
Control form=(Control)obj //强制转换为Control
form.Cursor = Cursors.WaitCursor;
mainAppExe = updaterXmlFiles.GetNodeValue("//EntryPoint");
Process [] allProcess = Process.GetProcesses();
foreach(Process p in allProcess)
{
if (p.ProcessName.ToLower() + ".exe" == mainAppExe.ToLower() )
{
for(int i=0;i<p.Threads.Count;i++)
p.Threads[i].Dispose();
p.Kill();
isRun = true;
//break;
}
}
应该没问题的了
第二种解决办法:
一定要使用鼠标等待效果的话,在UI线程设置成等待效果,然后用AutoResetEvent和WaitHandle控制线程的同步,后台线程运行完再设置为正常状态,不废话了
#3
嗯,那就是我的思路全错了
要改,后面的函数得全改
各位大哥,我初学,这一下子,完了,又得全新去看,而且还不知道怎么写了.
不过,非常感谢楼上二位的解答
特别感谢linq_chen ,因为我是新手,理论更难懂,有代码,有注释,让我受益非浅!!!
继续修改这个程序,希望能完善!
要改,后面的函数得全改
各位大哥,我初学,这一下子,完了,又得全新去看,而且还不知道怎么写了.
不过,非常感谢楼上二位的解答
特别感谢linq_chen ,因为我是新手,理论更难懂,有代码,有注释,让我受益非浅!!!
继续修改这个程序,希望能完善!
#4
在构造函数上加上这句话也可以
CheckForIllegalCrossThreadCalls = false;
CheckForIllegalCrossThreadCalls = false;
#5
在构造函数上加上这句话也可以
CheckForIllegalCrossThreadCalls = false;
才是正解
CheckForIllegalCrossThreadCalls = false;
才是正解
#6
谢谢楼主了