zoukankan      html  css  js  c++  java
  • 多线程遇到的问题与解决方案

    多线程的两种方式:

    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();
                }    
    View Code

    2、在类中添加字段,使用HashTable记录每个线程的状态,在线程内部更新和检查该表的状态,如线程都运行结束则在线程内部结束进程,如下:

    主线程在等待状态:Console.ReadLine();

    线程内部:

                    //初始化线程状态
                    htThreadStatus.Add(threadId, true);
                    while(true)
                    {
                        if(TaskQueue.Count > 0)
                       {...}
                        else
                        {
                                 //队列为空时退出,并将该线程状态置为false
                                htThreadStatus[threadId] = false;
                                isComplete = true;
                                ICollection hashValues = htThreadStatus.Values;
                                foreach (bool bol in hashValues)
                                {
                                    if (bol)
                                    {
                                        isComplete = false;
                                        break;
                                    }
    
                                }
                                if (isComplete)
                        System.Diagnostics.Process.GetCurrentProcess().Kill();
                                break;                           
                        }
                    }                        
    View Code
  • 相关阅读:
    Beyond Compare3 注册密钥和添加到右键菜单
    DLL文件无法删除怎么解决
    英语单词学习方法
    JSP+Servlet+JavaBean
    把Java程序打包成jar文件包并执行
    把java文件打包成.jar (jar命令详解)
    Java程序打包成jar包
    JDK
    使用JDK开发Servlet程序
    Jdk和Jre目录和三个lib目录说明----外部扩展jar包servlet,mysql,oracle等
  • 原文地址:https://www.cnblogs.com/MattCheng/p/4279534.html
Copyright © 2011-2022 走看看