• .net4.0新特性之线程同步


    有时候我们可能需要使用多线程来执行同一任务,这个任务可能包含多步,而每步之间可能并不相干,但是这个任务必须让所有步骤执行完成后才能够进入下一步。这就如同WF中的并行任务。在.net4.0之前我们可能需要几个类来做到同步。但是现在我们只需要1个类就OK。

    代码
    Console.WriteLine("任务启动");
    using (CountdownEvent cd = new CountdownEvent(1))
    {
    for (var i = 0; i < 5; i++)
    {
    cd.AddCount();
    System.Threading.ThreadPool.QueueUserWorkItem(
    (o)
    =>
    {
    //do something
    Console.WriteLine("线程:" +
    Thread.CurrentThread.ManagedThreadId
    + ",工作启动");
    Thread.Sleep(
    5000);
    cd.Signal();
    Console.WriteLine(
    "线程:" + Thread.CurrentThread.ManagedThreadId + ",工作完毕 ");
    });
    }
    cd.Signal();
    cd.Wait();
    }

    通过以上代码,我们看到只需要使用CountdownEvent类的AddCount() 和 Signal()方法 就可能实现线程同步。

    此外,还有一个类也能够实现线程同步:Barrier。然而这个类不是通过使用增加减少信号量来实现同步。在程序执行时我们可呢个为这个类定义需要接到几个信号后同步任务完成进入下一个任务。

    Barrier _barrier = new Barrier(3);//接到3个任务后同步目标达成,进入下一个任务。

     

    代码
    Barrier _bar = new Barrier(3);
    ThreadPool.QueueUserWorkItem(
    (o)
    =>
    {
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    _bar.SignalAndWait();
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId
    + "is complete");
    Thread.Sleep(
    2000);
    });
    ThreadPool.QueueUserWorkItem(
    (o)
    =>
    {
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    _bar.SignalAndWait();
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId
    + "is complete");
    Thread.Sleep(
    2000);
    });
    ThreadPool.QueueUserWorkItem(
    (o)
    =>
    {
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    _bar.SignalAndWait();
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId
    + "is complete");
    Thread.Sleep(
    2000);
    });
    //以上3个任务完成以后,下一个任务才会执行
    ThreadPool.QueueUserWorkItem(
    (o)
    =>
    {
    Thread.Sleep(
    2000);
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
    _bar.SignalAndWait();
    Console.WriteLine(Thread.CurrentThread.ManagedThreadId
    + "is complete");
    });

    使用Task类进行任务控制:

    1, 连续任务:

    代码
    Task<int> task1 = new Task<int>(() =>
    {
    Console.WriteLine(
    "Task1");
    return 1;
    });

    Task task2
    = task1.ContinueWith(
    (prev)
    =>
    {
    int result = prev.Result;
    Console.WriteLine(
    "Task2," + result);
    });
    //task1执行完以后执行这个任务
    task1.Start();

     2, 任务等待:

    代码
    Task t1 = Task.Factory.StartNew(() => { Console.WriteLine("task1"); });

    Task t2
    = Task.Factory.StartNew(() => { Console.WriteLine("task2"); });

    Task t3
    = Task.Factory.StartNew(() => { Console.WriteLine("task3"); });


    Task.WaitAll(t1, t2, t3);
    Console.WriteLine(
    "continue");

    3, 容器任务

    代码
    Task container = new Task(() =>
    {
    Task.Factory.StartNew(()
    => { Console.WriteLine("first"); });
    Task.Factory.StartNew(()
    => { Console.WriteLine("second"); });
    Task.Factory.StartNew(()
    => { Console.WriteLine("third"); });
    });
    container.Start();
    // 等待整个任务的完成
    container.Wait();
    Console.WriteLine(
    "continue");
    Console.ReadKey();

    4, 任务监视

    代码
    Task task1 = new Task(
    ()
    =>
    {
    Console.WriteLine(
    "task1 is start");
    int c = 0;
    while (c < 10)
    {
    Console.WriteLine(c);
    Thread.Sleep(
    1000);
    c
    ++;
    }
    });
    task1.Start();
    while (!task1.IsCompleted)
    {
    Console.WriteLine(
    "task1 not complete,wait...");
    Thread.Sleep(
    1000);
    }
    Console.WriteLine(
    "task1 is complete,continue!");
  • 相关阅读:
    大数的四则运算
    整数划分问题(递归法)
    浅谈C++中内存分配、函数调用和返回值问题
    栈的模拟运用 SOJ3897 dance2
    C/C++:sizeof('a')的值为什么不一样?
    浅谈C++中指针和引用的区别
    n!的分解 soj 2666
    char *a 和char a[] 的区别(指针和数组的区别)
    错排公式的推导
    浅谈C语言中的指针
  • 原文地址:https://www.cnblogs.com/GuoPeng/p/1812545.html
Copyright © 2020-2023  润新知