多線程訪問控件

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会调用消息处理程序。

  1. privatevoidbutton2_Click(objectsender,EventArgse)  
  2. {  
  3. for(inti=0;i<30;i++)  
  4. {  
  5. stringstringtext=string.Format("Item{0}",i);  
  6. ListViewItemlvi=newListViewItem(text,0);  
  7. this.listView1.Items.Add(lvi);  
  8. Thread.Sleep(200);  
  9. for(intj=0;j<10;j++)  
  10. {  
  11. Thread.Sleep(10);  
  12. Application.DoEvents();  
  13. }  
  14. }  
  15. }  
  16. 3.Lock  
  17. lock(object)  
  18. {  
  19. }  
  20. 等价与  
  21. try  
  22. {  
  23. Monitor.Enter(object);  
  24. }  
  25. finally  
  26. {  
  27. Monitor.Exit(object)  
  28. }

-------------------------------------------------------

// 可选,功用:即使该线程不结束,进程也可以结束
_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

你可能感兴趣的:(控件)