使用c#QueueUserWorkItem似乎不执行所有方法

时间:2012-02-08 16:05:54

标签: c# multithreading

以下是我的代码。

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Main thread starts and sleeps");
        Student stu = new Student();
        ThreadPool.QueueUserWorkItem(stu.Display, 7);
        ThreadPool.QueueUserWorkItem(stu.Display, 6);
        ThreadPool.QueueUserWorkItem(stu.Display, 5);
        Console.WriteLine("Main thread ends");
    }

}

public class Student
{
    public  void Display(object data)
    {
        Console.WriteLine(data);
    }
}

每次运行代码时,我都会得到不同的结果。我不是指它们的显示顺序。

以下是我的各种结果

Main thread starts and sleeps  
Main thread ends


Main thread starts and sleeps
Main thread ends
7
5
6


Main thread starts and sleeps
Main thread ends
7

那么,为什么我不能每次都显示所有三个数字。请帮忙。

2 个答案:

答案 0 :(得分:5)

那是因为你没有等待任务完成。它们排队等待在线程池上执行,但主线程在全部或部分线程完成之前退出。

要查看所有这些内容的完成,您需要在Main结束前使用同步屏障:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Main thread starts and sleeps");
        Student stu = new Student();
        ThreadPool.QueueUserWorkItem(stu.Display, 7);
        ThreadPool.QueueUserWorkItem(stu.Display, 6);
        ThreadPool.QueueUserWorkItem(stu.Display, 5);

        // barrier here
        Console.WriteLine("Main thread ends");
    }
}

不幸的是,C#没有ThreadPool的内置屏障,所以你需要自己实现一个,或者使用不同的构造,比如Parallel.Invoke

答案 1 :(得分:2)

ThreadPool个帖子是background threads,这意味着一旦主线程结束,它们就会被中止。由于没有人保证您的异步方法有可能在最后一个语句之前执行,因此每次都会得到不同的结果。