当前位置:编程学习 > C#/ASP.NET >>

我的关于线程的一些不理解的问题,请高手请教!!

  
  我写了一个Windows应用程序,在程序运行起来,启动一个线程,进行数据库操作,开始的时候我的线程函数是普通的类的程序函(就是主窗体这个类的程序函数),但是在调试时,发现程序进入线程中,就跑飞了,于是我换成静态函数,运行就没有问题。后来我想在线程函数运行过程中操作窗体中的控件,我打算使用委托来实现线程中操作控件,但是静态函数中好像又不能使用委托的对象,编译报错:非静态变量需要静态引用。现在不知道该怎么做了!!
  
  我的疑问是:

    1、线程函数使用静态与非静态的函数,什么情况下使用静态,什么时候使用非静态,有什么区别;
    2、线程函数与主窗口在同一个类中,使用静态,还是非静态的,使用非静态的为社么会出现我上述的程序跑飞的问题;
    

     请高手指教一下!!!! --------------------编程问答--------------------
   把我的测试代码发一下:
   Form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ThreadDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        
        }

        public static void mythreadproc()  //线程函数
        {
            //int i = 0;
            for (int i = 0; i < 100; i++)
            {
                Console.WriteLine(i.ToString());
                Thread.Sleep(1000);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(mythreadproc));
            t.Start();
        }
    }
}

///////////////
如果把函数mythreadproc改为非静态的,那么程序就会跑飞掉,请问这是怎么回事?? --------------------编程问答-------------------- 这个跟程序的Main函数一定要是静态函数是一个道理,如果入口函数是非静态函数,则在类实例化之前该函数不会被分配内存空间,线程也不会找到启动的入口点。静态函数在程序编译好后类加载时就会被分配内存空间,这样线程才能启动。 --------------------编程问答-------------------- 你所谓的跑飞了是什么意思。

线程 t 不能控制还是》。。。 --------------------编程问答-------------------- 但是我在网上看到很多线程函数不是静态的情况, --------------------编程问答--------------------
  就是在线程函数入口设置一个断点,然后F10之后程序就不知道去哪里了??

  另外,我看这个例子也是使用非静态函数作为线程函数??
http://www.4vsky.com/blogview.asp?logID=20 --------------------编程问答-------------------- 啥叫"跑飞"? --------------------编程问答-------------------- 并不是程序跑飞掉,而是进程停止了。同意2楼的观点。
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 
using System.Threading; 

namespace ThreadDemo 

    public partial class Form1 : Form 
    { 
        public Form1() 
        { 
            InitializeComponent(); 
        
        } 

        public void mythreadproc()  //线程函数 
        { 
            //int i = 0; 
            for (int i = 0; i < 100; i++) 
            { 
                Console.WriteLine(i.ToString()); 
                Thread.Sleep(1000); 
            } 
        } 

        static void main()
        {   Form1 F1 = new Form1();
            F1.yourThread(); 
        }

        public void yourThread ()
        {   Thread t = new Thread(new ThreadStart(mythreadproc)); 
            t.Start(); 
        }
    } 

--------------------编程问答-------------------- 并不是程序跑飞掉,而是“线程”停止了。同意2楼的观点。 
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 
using System.Threading; 

namespace ThreadDemo 

    public partial class Form1 : Form 
    { 
        public Form1() 
        { 
            InitializeComponent(); 
        
        } 

        public void mythreadproc()  //线程函数 
        { 
            //int i = 0; 
            for (int i = 0; i < 100; i++) 
            { 
                Console.WriteLine(i.ToString()); 
                Thread.Sleep(1000); 
            } 
        } 

        static void main() 
        {  Form1 F1 = new Form1(); 
            F1.yourThread(); 
        } 

        public void yourThread () 
        {  Thread t = new Thread(new ThreadStart(mythreadproc)); 
            t.Start(); 
        } 
    } 

照你那样,当start函数返回的时候,线程就会终止。或者没有调用Start,你调用其它函数,做其它动作也会终止。 --------------------编程问答-------------------- 我的疑问是: 

    1、线程函数使用静态与非静态的函数,什么情况下使用静态,什么时候使用非静态,有什么区别; 
    2、线程函数与主窗口在同一个类中,使用静态,还是非静态的,使用非静态的为社么会出现我上述的程序跑飞的问题; 
    
答:
1:静态与非静态函数对于线程来说没有本质上的区别。使用静态与非静态完全取决于你的线程的需要。
静态函数适合于线程数目固定的情况。比如你需要一个精度不太高的定时器你可以这样做:

public static class MySingleTimer
{
public static delegate Notify();
public Notify note;
public static void Timer()
{
while(true)
{
Thread.Sleep(500);
note();
}
}
}

这是个静态类,你可以把任何一个无参数的、返回值为void的函数赋值给note,然后每隔500ms,就会执行一次这个函数。
但是你的系统中只有一个这样的线程。如果你的程序中同时需要多个计时器,每个可能的时间都不相同,执行的函数也不同,这时你可以写成性:

public class MyTimer
{
public delegate Notify();
public note;
public void Timer()
{
while(true)
{
Thread.Sleep(500);
note();
}
}
public void Start()
{
Thread t = new Thread(new ThreadStart(Timer));
t.Start();
}
}

public static Main()
{
MyTimer mt1 = new MyTimer();
mt1.note = SomeFunction1();
MyTimer mt2 = new MyTimer();
mt2.note = SomeFunction2();

}

第一个类代码我没有写线程的声明、初始化和启动的代码。上面这个我写了,因为我看到上面的讨论提到了静态函数、主函数与入口点的问题。以上面的这个为例,非静态的函数、线程是完全可以实现并运行的。

至于你的程序跑飞什么的,首先要说你的描述似乎不太精确。我试试看你的代码。


--------------------编程问答-------------------- 你的二个代码我都在VS2008下调试了,没有出现你说的飞了的情况。mythreadproc无论是第一段代码还是第二段代码均可正常的单步调试。
我估计是其它原因导致的这个结果,你需要再检查有无其它可能导致此类故障的情况。另外多用日志或者DEBUGOUT之类的工具输出程序中的异常。 --------------------编程问答-------------------- 刚才突然想到一个可能的原因,你检查一下看你的主程序是否在工作?
如果你的线程没有设置为background的情况下,按道理主线程中止后这个线程还会运行。由于你是使用的Main()函数中手工创建Form1窗口而不是使用Application.Run(new Fomr1())这样的方式。使用你的这种方式会使主线程在调用完F1.youThread()后立刻中止,从而对其它线程产生影响。 --------------------编程问答-------------------- phy说的不错
看来我对线程和程序运行的机制还是不了解
学习
补充:.NET技术 ,  C#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,