多线程的两种方式:
1、线程池
ThreadPool.QueueUserWorkItem(...);
或者使用委托:
ParameterizedThreadStart start = new ParameterizedThreadStart(handleProtocol);
start.BeginInvoke(pro, null, null);
2、自定义线程
Thread myThead = new Thread(...);
myThead.Start(...);
遇到的问题:
使用线程池,在线程中创建WebBrowser对象时,会出现异常:“
ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current...
”
一种解决思路是使用自定义线程:
1 Thread myThead = new Thread(...); 2 myThead.SetApartmentState(ApartmentState.STA); 3 myThead.Start(...);
该方案虽然可以正常创建WebBrowser,但控件的消息响应无法触发,即页面加载完成的处理程序无法执行(原因估计是线程设为单一线程)。
一种解决思路是在主线程中创建WebBrowser对象,并将对象的引用传给开启的线程:
1 WebBrowser browser = new WebBrowser(); 2 browser.Navigate(...); // 这步是必须的,否则会报异常:无法获取“WebBrowser”控件的窗口句柄。不支持无窗口的 ActiveX 控件。 3 Thread myThead = new Thread(...);
4 myThead.Start(new object[]{browser});
该方案在程序刚执行时正常,之后页面加载异常(但是程序仍在正常执行,原因未知)。
一种解决思路是在主线程中创建WebBrowser对象,并使用线程池,所出现的问题如上一思路。
可行的方案待研究...
Thread.ApartmentState 默认值:MTA
Thread.IsBackground 默认值:false (即为前台线程)
线程池中的线程为后台线程(backgournd thread)
跑批程序的两种多线程管理方式:
1、使用数组保存线程对象,之后Thread.Join方法等待线程结束,如下:
Thread[] tds = new Thread[tmpThreadCount]; while (tmpThreadCount >= 1) { Thread t = new Thread(new ThreadStart(ProcessTask)); t.IsBackground = true; t.Start(); tmpThreadCount--; tds[tmpThreadCount] = t; } for (int i = 0; i < tds.Length; i++) { tds[i].Join(); }