1个listview,从数据库取得站点地址,然后通过一个方法得到站点的状态,是通还是不通
然后将状态的图片加到listview上
我在一个菜单里重新执行它时,并没有起作用,我不知道是线程还没有结束还是其他错误?        private int PageStatus;
        private string SiteUrl;
        private int order;
        private string SiteName;private void Main_Load(object sender, EventArgs e)
        {
            GetSitesList();
        }
public void GetSitesList()
        {
            SitesList.Items.Clear();
            SitesList.Columns.Clear();
            SitesList.Columns.Add("站点名称");
            SitesList.Columns.Add("域名");
            SitesList.Columns[0].Width = 90;
            SitesList.Columns[1].Width = 122;
            try
            {
                SqlConnection conn = new SqlConnection(App_Code.dbConnection.GetConnect().ToString());
                conn.Open();
                SqlCommand cmd = new SqlCommand(@"select * from SiteInfo", conn);
                SqlDataReader MyReader = cmd.ExecuteReader();
                while (MyReader.Read())
                {
                    ListViewItem li = new ListViewItem();
                    li.SubItems[0].Text = MyReader["SiteName"].ToString();
                    li.SubItems.Add(MyReader["SiteUrl"].ToString());
                    SitesList.Items.Add(li);
                    SiteUrl = MyReader["SiteUrl"].ToString();
                    for (; order < this.SitesList.Items.Count; )
                    {
                        Thread oThread = new Thread(new ThreadStart(GetPage));//这里是取得状态,比较费时
                        oThread.Start();
                        Thread.Sleep(100);
                        order++;
                    }
                }
                conn.Close();
            }
            catch (Exception exp)
            {
                
            }
        }public void GetPage()
        {
            int temp = order;
            string Html = App_Code.WebHelp.GetWebPage("http://" + SiteUrl, "UTF-8");
            if (Html == "Error")
            {
                PageStatus = 2;
            }
            else
            {
                PageStatus = 0;
            }
            SitesList.BeginInvoke(new SetImageIndex(SetImg), new object[] { temp, PageStatus });//把图加到listview
        }
public delegate void SetImageIndex(int itemindex, int imageindex);public void SetImg(int itemindex, int imageindex)
        {
            this.SitesList.Items[itemindex].ImageIndex = imageindex;
        }
//然后我在菜单里想刷新,或是在定时里去执行它private void 刷新站点ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            GetSitesList();
        }
//然后它输出的结果就只有站点列表,而不能去检测站点状态了,请高手指点,谢谢.

解决方案 »

  1.   

     你中断一下,看下有哪些线程在执行吧~~光看看不出什么,有个地方你考虑下,用下锁~~,因为你是并发操作--SitesList这个对象用下锁  App_Code.WebHelp.GetWebPage这里会阻塞吗
      

  2.   

    线程执行结束后就不能再start了吗?有什么办法解决?
      

  3.   

    我调试了,我点刷新的时候在这里:
                        for (; order < this.SitesList.Items.Count; )
                        {
                            Thread oThread = new Thread(new ThreadStart(GetPage));//这里是取得状态,比较费时
                            oThread.Start();
                            Thread.Sleep(100);
                            order++;
                        }
    for的时候就没有进循环,直接执行后面的代码了,不知道为什么
      

  4.   

    1.使用线程的情况 
    ①.程序需要执行和两个和多个任务 
    ②.程序要等待某事件的发生:例如用户输入、文件操作、网络操作和搜索 
    ③.后台程序 2.多线程的并发执行 
    如果有多个线程在执行,单CPU只有一个,到底执行的哪个? 
    ①.如果一个线程连续占用CPU资源时间过长,其它的资源得不到执行, 
    则系统会强制的切换执行其它线程。(强制剥夺) 
    ②.如果一个线程没事可做、CPU可执行其它线程。(主动放弃) 
    ③.这是由操作系统的调度机制决定的,不同的操作系统调度机制不一样。 
    一般无法精确的预料多线程的执行顺序,在程序设计的时候应特别注意 
    3.创建并启动线程 
    ThreadStart 线程启动委托名=new ThreadStart(方法名); 
    Thread 线程实例名=new Thread(线程启动委托名); 
    线程实例名.Start(); 
    4.终止线程 
    ①.线程实例名.Abort();用此方法的后果是不可恢复的终止线程。 
    ②.线程实例名.Interrupt();中断后可恢复 
    5.休眠线程 
    ①.线程实例名.Sleep(); 
    当线程Sleep时,系统就立即退出执行队列一段时间,当睡眠结束时,系统会产生一个时钟中断,从而 
    使线程回到执行队列中,从而恢复线程的执行。 
    6.挂起/恢复线程 
    ①.线程实例名.Suspend();挂起 
    与线程休眠不同,线程的挂起不会使线程立即停止执行,直到线程到达安全点之后它才可以将该 线程挂起,如果线程尚未启动或已经停止,则它将不能挂起。 
    ②.线程实例名.Resume();恢复 
    将使一个线程跳出挂起状态并使该线程继续执行。 
    一个线程不能对另一个线程调用Sleep() ,但是一个线程可以对另一个线程调用Suspend()。 
    还可以使用许多其它的方式来阻塞线程。例如,可以通过调用 Thread.Join 使一个线程等待另一个线程 (子线程)停止。使用Monitor.Wait使一个线程等待访问一个同步对象。 
    7.串行化线程 
    ①.线程实例名.jion(); 
    例如在主线程中插入t.jion(); 
    主线程执行到这条语句后,主线程(当前线程)立即进入阻塞状态.直到t运行完后阻塞状态才解除。 相当于把t的任务插入或串联到主线程中,把两条线索串联成一条线索 
    8.线程的锁定机制 
    线程的锁定机制可以保证每次只有一个线程可以访问共享资源。 
    使用关键字lock 
    ①.lock语句的语法 
    lock(对象引用)语句块; 
    ②.lock语句的功能 
    当对象被lock 锁定时,访问该线程的其它线程会进入等待的状态。 
    ③.对象锁机制保证了对象访问的完整性:只有一个线程完成操作后,其它的线程才能进行操作。 
    ④.一般情况下,当一个线程写某个变量,而同时可能有其它的线程读或写这个变量时,为了保持数据的一 致性应该使用锁定机制。 
    ⑤.线程的安全性 
    线程安全性就是保护的类的成员和代码的安全,从而使他们不会同时被几个线程中断,使用锁定机制。 
    ⑥.多线程公用一个对象时,就不应该使用lock关键字了,这里Monitor,Monitor提供了使线程共享资源的方 案。
    Monitor类可以锁定一个对象,一个线程只有得到这把锁才可以对该对象进行操作。 
    如: 
    Monitor.Enter(obj); 
    Monitor.Exit(obj); 
    ⑦.临界区和锁 
    当谈论多线程应用程序的时候,首先应该想到的就是并发性问题。尽管这对于同时执行多个任务的程序是很有用的,但通常都是危险的。为了解决这个问题,在C#中提出了临界区和锁的概念。在程序设计中,临界区是一块在任何时候只能有一个进程进入的区域。在C#中通过语句lock来声明临界区。lock声明后面的代码,不管是以行还是一块代码,在同一时间最多只能有一个进程执行。 9.线程的优先级具有不可靠性,就是说不能用优先级来控制线程的执行顺序。 10.后台线程 
    ①.什么是后台线程?比起应用程序的主图形用户界面(GUI)线程来说,这些线程以较低的优先权在不同的过程中 运行着。对于不能立即执行结束, 又不想一直等待的任务,后台线程能很好的胜任。在C#中,把线程对象的 IsBackground属性设为true,该线程即为后台线程。 
    后台线程跟前台线程只有一个区别,那就是后台线程不妨碍程序的终止。一旦一个进程所有的前台线程都终止后, CLR将通过调用任意一个存活中的后台进程的Abort()方法来彻底终止进程。  
      

  5.   

    好像不是线程的问题,你的order++;好像没有恢复缺省值,导致刷新后,线程没执行