如何验证n个方法是否并行执行?

Fra*_*zzi 5 c# task-parallel-library

仅出于知识目的,如何验证n个方法是否并行执行?

Parallel.For(0, 10, i => DoSomething(i));

...

void DoSomething(int par)
{
    Console.WriteLine($"Test: {par}");
}
Run Code Online (Sandbox Code Playgroud)

是否有测试可以向我保证DoSomething不是按顺序执行的(如果Console.WriteLine不是一个好的测试,那可能是一个非常简单的测试函数?)

J..*_*... 5

在您的示例中,方法肯定是顺序的,因为.NET控制台将同步来自不同线程的调用.

但是,您可以使用Thread.ManagedThreadIDEnvironment.CurrentManagedThreadId(对于.NET 4.5)检查运行该方法的线程ID

class Program
{
    static void Main(string[] args)
    {
        // first run with default number of threads
        Parallel.For(0, 10, i => DoSomething(i));
        Console.ReadLine();

        // now run with fewer threads...
        Parallel.For(0, 10, new ParallelOptions{ 
                                  MaxDegreeOfParallelism = 2 
                                }, i => DoSomething(i));
        Console.ReadLine();
    }

    static void DoSomething(int par)
    {
        int i = Environment.CurrentManagedThreadId;
        // int i = Thread.ManagedThreadId;  -- .NET 4.0 and under
        Thread.Sleep(200);
        Console.WriteLine("Test: "+ par.ToString() + 
                          ", Thread :" + i.ToString());
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你运行它没有Thread.Sleep你会注意到只会使用几个线程,因为调用将足够快地完成,以便线程及时返回到池以获取队列分配的下一个作业.

添加睡眠将延迟线程(模拟工作)足够长的时间,以至于线程池必须获取更多线程以及时将作业分离出来.

当并行运行任何任务时,很容易检查这些任务实际上是否都在不同的线程中运行.但是,您是否获得性能优势将取决于这些线程的工作效率.正如您所见,某些操作会调用共享资源上的争用(例如写入控制台),并可能阻止您的多个线程同时运行.

其他争用的来源可能是,例如,内存分配 - 如果您的线程都在大量分配和解除分配内存,那么他们最终可能会花费大量时间等待轮到内存管理器.这将限制您将实现的实际并行度.