C# 教程 在线

2441C# 多线程

笔记三的补充:

Thread childThread = new Thread( new ThreadStart(CallToChildThread));

Thread childThread = new Thread(CallToChildThread);

这两种写法的效果是一样的。都是创建一个线程。后者只是 C# 的语法,编译时编译器会自动转换成第一种的形式。ThreadStart 是线程的入口,可以理解为一个函数指针,指向线程将要运行的函数。

2440C# 多线程

C# 在 4.0 以后一共有3种创建线程的方式:

  • 1.Thread 自己创建的独立的线程, 优先级高,需要使用者自己管理。
  • 2.ThreadPool 有 .Net 自己管理, 只需要把需要处理的方法写好, 然后交个.Net Framework, 后续只要方法执行完毕, 则自动退出。
  • 3.Task 4.0 以后新增的线程操作方式, 类似 ThreadPool, 但效率测试比ThreadPool略高, Task对多核的支持更为明显,所以在多核的处理器中, Task的优势更为明显。
class Program
{  
    static void Main(string[] args)
    {  //独立创建线程
        Thread t = new Thread(ThreadProcess);
        t.Start(new object());
        
        //线程池
        ThreadPool.QueueUserWorkItem(ThreadProcess, new object());
        //Task方式创建线程
        System.Threading.Tasks.Task.Factory.StartNew(ThreadProcess, new object());

        //需要手动终止,当然现在终止可能线程还未运行完成,
        t.Abort();
    }
    private static void ThreadProcess(object tag)
    {
        int i = 100;
        while (i > 0)
        {
            Console.WriteLine(string.Format("i:{0} ", i));
            Thread.Sleep(10);
            i--;
        }
    }
}

2439C# 多线程

本篇文章的第二段代码创建线程中,在2.0以后可以直接执行子线程,这样一来程序可以省略Main函数中的第一行代码。运行结果一样,似乎程序会更简单易懂点。如下:

using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApp
{
    class Program
    {
        public static void CallToChildThread()
        {
            Console.WriteLine("Child thread starts");
        }

        static void Main(string[] args)
        {
            //ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            Thread childThread = new Thread(CallToChildThread);
            childThread.Start();
            Console.ReadKey();
        }
    }
}

2438C# 多线程

线程的销毁

(1)线程自动销毁

Thread a=new Thread(Method) th.start();

线程方法Method执行完结,线程a也自动终止.

(2)如果是无限循环需要手动销毁

窗体应用程序的线程间通信

.net 2.0以后加强了安全机制,不允许在winform中直接跨线程访问控件的属性。

线程函数通过委托传递,是一种安全的线程间通信的方式。也是委托的功能之一。

但C#也可以关闭线程安全保护,自由的调用其他线程生成的控件。只要加上

Control.CheckForIllegalCrossThreadCalls = false;

但不推荐使用。自己练习时可以写着玩一下。

2437C# 多线程

线程函数通过委托传递,可以不带参数,也可以带参数(只能有一个参数),可以用一个类或结构体封装参数:

using System;
using System.Threading;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread t1 = new Thread(new ThreadStart(TestMethod));
            Thread t2 = new Thread(new ParameterizedThreadStart(TestMethod));
            t1.IsBackground = true;
            t2.IsBackground = true;
            t1.Start();
            t2.Start("hello");
            Console.ReadKey();
        }

        public static void TestMethod()
        {
            Console.WriteLine("不带参数的线程函数");
        }

        public static void TestMethod(object data)
        {
            string datastr = data as string;
            Console.WriteLine("带参数的线程函数,参数为:{0}", datastr);
        }
    }
}