多線程訪問控件
this.Invoke((MethodInvoker)delegate()
{
ctBtnOk1.Enabled = true;
});
使用lock(this)防止進程退出,線程還未處理完問題,高試時會有提示:
private void UserThread()
{
try
{
this.Invoke((MethodInvoker)delegate()
{
//防止窗體內存回收
//PreLoadForm(new LoadDevXtraForm());
//PreLoadForm(new LoadDevXtraForm2());
//PreLoadForm(new ShopIdForm());
panel3.Visible = false;
ctBtnOk1.Enabled = true;
});
lock (this)
{
App.OsConfig = licenseKey.GetOsconfig();
}
}
catch (Exception err)
{
this.Invoke((MethodInvoker)delegate()
{
//MessageHandle.MessageShow(this, err.Message);
});
return;
}
}
-------------------------------------------------------
1.Invoke和BeginInvoke
在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,正确的做法是将工作线程中涉及更新界面的代码封装为一个方法,通过Invoke或者BeginInvoke去调用,两者的区别就是一个导致工作线程等待,而另外一个则不会。
而所谓的“一面响应操作,一面添加节点”永远只能是相对的,使UI线程的负担不至于太大而以,因为界面的正确更新始终要通过UI线程去做,我们要做的事情是在工作线程中包揽大部分的运算,而将对纯粹的界面更新放到UI线程中去做,这样也就达到了减轻UI线程负担的目的了。
2.Application.DoEvent
在耗时的循环的UI更新的方法中,插入Application.DoEvent,会使界面获得响应,Application.DoEvent会调用消息处理程序。
- privatevoidbutton2_Click(objectsender,EventArgse)
- {
- for(inti=0;i<30;i++)
- {
- stringstringtext=string.Format("Item{0}",i);
- ListViewItemlvi=newListViewItem(text,0);
- this.listView1.Items.Add(lvi);
- Thread.Sleep(200);
- for(intj=0;j<10;j++)
- {
- Thread.Sleep(10);
- Application.DoEvents();
- }
- }
- }
- 3.Lock
- lock(object)
- {
- }
- 等价与
- try
- {
- Monitor.Enter(object);
- }
- finally
- {
- Monitor.Exit(object)
- }
-------------------------------------------------------
// 可选,功用:即使该线程不结束,进程也可以结束
_progressThread.IsBackground = true;
-------------------------------------------------------
C#2005后不再支持多线程直接访问界面的控件(界面创建线程与访问线程不是同一个线程),不过可以使用delegate来解决:
1. 声明一个delegate和定义一个delegate的实现函数
delegate void ShowProgressDelegate(int newPos);
private void ShowProgress(int newPos)
{
// 判断是否在线程中访问
if (!_progressBar.InvokeRequired)
{
// 不是的话直接操作控件
_progressBar.Value = newPos;
}
else
{
// 是的话启用delegate访问
ShowProgressDelegate showProgress = new ShowProgressDelegate(ShowProgress);
// 如使用Invoke会等到函数调用结束,而BeginInvoke不会等待直接往后走
this.BeginInvoke(showProgress, new object[] { newPos });
}
}
2. 定义线程函数(在另一个线程中可以对界面控件进读操作)
private void ProgressStart()
{
while (true)
{
int newPos = _progressBar.Value + 10;
if (newPos > _progressBar.Maximum)
{
newPos = _progressBar.Minimum;
}
Trace.WriteLine(string.Format("Pos: {0}", newPos));
// 这里直接调用方法,由其内部自动判断是否启用delegate
ShowProgress(newPos);
Thread.Sleep(100);
}
}
3. 线程的启动和终止
private Thread _progressThread;
_progressThread = new Thread(new ThreadStart(ProgressStart));
// 可选,功用:即使该线程不结束,进程也可以结束
_progressThread.IsBackground = true;
_progressThread.Start();
_progressThread.Abort();
// 可选,功用:等到线程结束才继续
_progressThread.Join();
_progressThread = null;
-------------------------------------------------------
user controls Could not load file or assembly or one of its dependencies. The system cannot find the file specified.
http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_24529170.html
http://stackoverflow.com/questions/8103969/winforms-designer-breaks-after-a-recompile
http://msdn.microsoft.com/en-us/library/e74a18c4%28v=vs.100%29.aspx
http://stackoverflow.com/questions/6952460/where-does-visual-studio-look-for-assemblies?rq=1
http://www.codeproject.com/Articles/21396/Visual-Studio-Designer-Cache-Hell