c#线程初探

来源:互联网 发布:java 判断类型 编辑:程序博客网 时间:2024/04/30 14:26

c#和.net基类为开发多线程应用程序提供了强大的支持。下面是我看书和结合网上的一些资源整理出来的笔记。因为线程相关的知识比较繁杂和高深(并且本人开发经验欠缺),所以写的很浅显甚至幼稚,理解不妥之处在所难免。
1.怎样创建一个线程(常用的创建方式)


using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;

namespace ThreadStudy
{
    
public class MyThreadClass
    {
        
public static void ThreadTest()
        {
            Console.WriteLine(
"This is a thread test.The worker thread is started!");
        }
        
public static void ThreadTestWithParameter(object stateInfo)
        {
            Console.WriteLine(
string.Format("This is {0}.The worker thread is started!", stateInfo));
        }
        
delegate void ThreadTestDelegate(object objName);

        
static ThreadTestDelegate myTest = new ThreadTestDelegate(ThreadTestWithParameter);

        
//线程完成之后回调的函数
        public static void TaskFinished(IAsyncResult result)
        {
            
// myTest.EndInvoke(result); //无返回值
            Console.WriteLine("Thread test callback end.");
        }

        
/* 怎样创建一个线程? */
        
public static void Main()
        {
            
//1.使用Thread类 
            /*a、无参数委托*/
            ThreadStart ts 
= new ThreadStart(ThreadTest); //通过ThreadStart委托(无参数)告诉子线程讲执行什么方法
            Thread currentThread = new Thread(ts);
            currentThread.Name 
= "my first thread test without parameter"//给线程起名字,不是必须的
            currentThread.Start(); //启动新线程
            currentThread.Abort();
            Thread.Sleep(
2000);
            
/*b、带参数委托*/
            ParameterizedThreadStart pts 
= new ParameterizedThreadStart(ThreadTestWithParameter); //通过ParameterizedThreadStart委托(参数)告诉子线程讲执行什么方法
            Thread curThread = new Thread(pts);
            curThread.Name 
= "my first thread test with parameter(s)"//给线程起名字,不是必须的
            curThread.Start("my first thread test with a parameter");//启动新线程,出入一个参数(也可以多个参数)
            curThread.Abort();
            Thread.Sleep(
2000);

            
//2.使用ThreadPool类 
            WaitCallback wcb = new WaitCallback(ThreadTestWithParameter); //通过WaitCallback委托(可以带参数,也可不带参数,这里的实例是带参数的)告诉子线程讲执行什么方法
            ThreadPool.QueueUserWorkItem(wcb, "my first threadpool test");
            ThreadPool.QueueUserWorkItem(ThreadTestWithParameter, 
"my second threadpool test");

            Thread.Sleep(
2000);

            
//3.使用Delegate.BeginInvoke 
            myTest.BeginInvoke("my thread test without callback"nullnull);//此处开始异步执行,如果不需要执行什么后续操作也可以不使用回调

            Thread.Sleep(
2000);

            
//适用于需要传递参数且需要返回参数 
            myTest.BeginInvoke("my thread test with call back"new AsyncCallback(TaskFinished), null);//此处开始异步执行,并且可以给出一个回调函数


            
/* 最后获取当前正在运行的线程的一些信息 */
            Console.WriteLine(Thread.CurrentThread.CurrentCulture.ToString());
            Console.WriteLine(Thread.CurrentThread.CurrentUICulture.ToString());
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString());
            Console.WriteLine(Thread.CurrentThread.IsThreadPoolThread.ToString());
            Console.WriteLine(Thread.CurrentThread.IsAlive.ToString());
            Console.WriteLine(Thread.CurrentThread.IsBackground.ToString());
            Console.WriteLine(Thread.CurrentThread.Priority.ToString());

            Console.Read();
        }
    }
}

2.线程的优先级
如果在应用程序中有多个线程在运行,但一些线程比另外的一些线程重要,这时候就要用到线程的优先级。一般情况下,优先级高的线程在工作时,就不会给优先级低的线程分配任何时间片。高优先级的线程可以完全阻止低优先级的线程执行,因此在改变线程优先级的时候要特别小心。
线程的优先级可以定义为枚举ThreadPriority,即Highest,AboveNormal,Normal,BelowNormal和Lowest。


using System;
using System.Threading;

class Program
{
    
static int interval;
    
static void Main()
    {
        Console.WriteLine(
"Please input a number:");
        interval 
= int.Parse(Console.ReadLine());
        Thread curThread 
= Thread.CurrentThread;
        curThread.Name 
= "Main Thread";

        ThreadStart ts 
= new ThreadStart(StartMethod);
        Thread workerThread 
= new Thread(ts);
        workerThread.Name 
= "Worker Thread";
        workerThread.Priority 
= ThreadPriority.AboveNormal; //线程优先级
        workerThread.Start();

        DisplayNumbers();
        Console.WriteLine(
"Main Thread Finished!");

        Console.ReadLine();
    }

    
static void DisplayNumbers()
    {
        Thread thisThread 
= Thread.CurrentThread;
        
string name = thisThread.Name;
        Console.WriteLine(
"Starting Thread:" + name);
        Console.WriteLine(name 
+ ":CurrentCulture=" + thisThread.CurrentCulture);
        
for (int i = 0; i < 6 * interval; i++)
        {
            
if (i % interval == 0)
            {
                Console.WriteLine(name 
+ ":count has reached " + i);
            }
        }
    }

    
static void StartMethod()
    {
        DisplayNumbers();
        Console.WriteLine(
"Worker Thread Finished!");
    }
}

 在下一篇会接着介绍关于c#线程的“同步”相关知识。这里先打住,因为正在看书,还没消化过来^_^

 

 

 

我们如果定义不带参数的线程,可以用ThreadStart,带一个参数的用ParameterizedThreadStart。带多个参数的用另外的方法,下面逐一讲述。

一、不带参数的

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace AAAAAA
{
    
class AAA
    
{
        
public static void Main()
        
{
            Thread t 
= new Thread(new ThreadStart(A));
            t.Start();

            Console.Read();
        }


        
private static void A()
        
{
            Console.WriteLine(
"Method A!");
        }

    }

}

 

      结果显示Method A!

二、带一个参数的

     由于ParameterizedThreadStart要求参数类型必须为object,所以定义的方法B形参类型必须为object。

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace AAAAAA
{
    
class AAA
    
{
        
public static void Main()
        
{         
            Thread t 
= new Thread(new ParameterizedThreadStart(B));
            t.Start(
"B");

            Console.Read();
        }


        
private static void B(object obj)
        
{
            Console.WriteLine(
"Method {0}!",obj.ToString ());

        }

    }

}

 

 结果显示Method B!

三、带多个参数的

     由于Thread默认只提供了这两种构造函数,如果需要传递多个参数,我们可以自己将参数作为类的属性。定义类的对象时候实例化这个属性,然后进行操作。

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace AAAAAA
{
    
class AAA
    
{
        
public static void Main()
        
{
            My m 
= new My();
            m.x 
= 2;
            m.y 
= 3;

            Thread t 
= new Thread(new ThreadStart(m.C));
            t.Start();

            Console.Read();
        }

    }


    
class My
    
{
        
public int x, y;

        
public void C()
        
{
            Console.WriteLine(
"x={0},y={1}"this.x, this.y);
        }

    }

}

 

     结果显示x=2,y=3

四、利用结构体给参数传值。

定义公用的public struct,里面可以定义自己需要的参数,然后在需要添加线程的时候,可以定义结构体的实例。

//结构体
  struct RowCol
    
{
        
public int row;
        
public int col;
    }
;

//定义方法
 public void Output(Object rc)
        
{
            RowCol rowCol 
= (RowCol)rc;
            
for (int i = 0; i < rowCol.row; i++)
            
{
                
for (int j = 0; j < rowCol.col; j++)
                    Console.Write(
"{0} ", _char);
                Console.Write(
"/n");
            }

        }
原创粉丝点击