zoukankan      html  css  js  c++  java
  • Task , Thread 学习


    1.任务StartNew后就开始执行,使用Wait()来确保任务结束后继续

    static void Main(string[] args)
            {
                try
                {
                    int numberOfUsers = 100;
                    var users = new string[20];
                    for (int i = 0; i < 20; i++)
                    {
                        users[i] = string.Format("LoadTest{0}", i + 1);
                    }
    
                    Task t = Task.Factory.StartNew(() => WriteLog(users[5]));
                    Thread.Sleep(5000);
                    Console.WriteLine("Is first one start?");
                    Task t1 = Task.Factory.StartNew(() => WriteLog(users[6]));
                    Thread.Sleep(5000);
                    Console.WriteLine("Are they start?");
                    Thread.Sleep(5000);
                    t1.Wait();
                    Console.WriteLine("Will End soon!");
                    t.Wait();
                    Thread.Sleep(500000000);
    
                }
                catch (Exception ex)
                {
                    Console.WriteLine(string.Format("Time {0}:{1}",DateTime.Now, ex.Message));
                    Thread.Sleep(500000000);
                }
            }
    
            private static void WriteLog(string userName)
            {
                Console.WriteLine(string.Format("Begin Time {0}:ProcessId {2} ThreadId {3} {1}", DateTime.Now, userName, System.Diagnostics.Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId));
                Thread.Sleep(5000);
                if (userName == "LoadTest2")
                {
                    Thread.Sleep(5000);
                    throw new Exception("Lazy!");
                }
                Console.WriteLine(string.Format("End Time {0}:ProcessId {2} ThreadId {3} {1}", DateTime.Now, userName, System.Diagnostics.Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId));
            }



    执行效果:


    使用ThreadPool也是同样效果:

        foreach (string user in users)
        {
            ThreadPool.QueueUserWorkItem(arg =>
            {
                WriteLog(user);
            });
                }

    2.10个任务一起执行,须注意WriteLog的参数不能直接使用i,因为在实际开始工作的时候i值已经变成了10

    Task[] ts = new Task[10];
    for(int i=0;i < numberOfUsers ; i++ ) 
    {
    ts[i] = Task.Factory.StartNew((object obj) => {
       int j = (int)obj;
       WriteLog(users[j]); }, i);
    }
    Task.WaitAll(ts); 
    Console.WriteLine("Will End soon!");
    Thread.Sleep(500000000);




    3.总共20个人,后10个人接着前面10个人后干活,使用ContinueWith , 其中传的prevTask可以得到前面任务的状态
    static void Main(string[] args)
            {
                try
                {
                    int numberOfUsers = 10;
                    var users = new string[20];
                    for (int i = 0; i < 20; i++)
                    {
                        users[i] = string.Format("LoadTest{0}", i + 1);
                    }
    
                    Task[] ts = new Task[numberOfUsers];
                    for (int i = 0; i < numberOfUsers; i++)
                    {
                        ts[i] = Task.Factory.StartNew((object obj) =>
                        {
                            int j = (int)obj;
                            WriteLog(users[j]);
                        }, i).ContinueWith((prevTask) =>
                        {
                            string exp = string.Empty;
                            if (prevTask.Exception!=null )  exp = "Exception:" + prevTask.Exception.Message;
                            Console.WriteLine(string.Format("ID:{0} Status:{1} IsCanceled:{2} IsCompleted:{3} {4}", prevTask.Id, prevTask.Status, prevTask.IsCanceled, prevTask.IsCompleted, exp));
                            WriteLog(users[9 + prevTask.Id]);
                        });
                       
                    }
                    
                    Task.WaitAll(ts);
                    Console.WriteLine("Will End soon!");
                    Thread.Sleep(500000000);
    
                }
                catch (Exception ex)
                {
                    Console.WriteLine(string.Format("Time {0}:{1}",DateTime.Now, ex.Message));
                    Thread.Sleep(500000000);
                }
            }



    4.获取UI上的值来控制是否cancel一个任务下面的所有子任务,使用CancellationTokenSource
    static void Main(string[] args)
            {
                try
                {
                    int numberOfUsers = 10;
                    var users = new string[numberOfUsers];
                    for (int i = 0; i < numberOfUsers; i++)
                    {
                        users[i] = string.Format("LoadTest{0}", i + 1);
                    }
                    CancellationTokenSource tokenSource = new CancellationTokenSource();
                    CancellationToken  token = tokenSource.Token;
                    ConcurrentBag<Task> ts = new ConcurrentBag<Task>();
                    Console.WriteLine("Press any key to begin tasks...");
                    Console.WriteLine("To terminate the example, press 'c' to cancel and exit...");
                    Console.ReadKey();
                    Console.WriteLine();
    
    
                    //Task t = Task.Factory.StartNew(() => WriteLog(users[0], token), token);
                    //Console.WriteLine("Task {0} executing", t.Id);
                    //ts.Add(t);
    
                    Task t = Task.Factory.StartNew(() =>
                    {
                        Task tc;
                        for (int i = 0; i < numberOfUsers; i++)
                        {
                            tc = Task.Factory.StartNew((object obj) =>
                            {
                                int j = (int)obj;
                                WriteLog(users[j], token);
                            }, i, token);
                            ts.Add(tc);
                        }
                    },token);
                    ts.Add(t);
    
                    if (Console.ReadKey().KeyChar == 'c')
                    {
                        tokenSource.Cancel();
                        Console.WriteLine("
    Task cancellation requested.");
                    }
                    try
                    {
                        Task.WaitAll(ts.ToArray());
                    }
                    catch (AggregateException e)
                    {
                        foreach (var v in e.InnerExceptions)
                        {
                            if (v is TaskCanceledException)
                                Console.WriteLine("   TaskCanceledException: Task {0}",
                                                  ((TaskCanceledException)v).Task.Id);
                            else
                                Console.WriteLine("   Exception: {0}", v.GetType().Name);
                        } 
    
                    }
                    Console.WriteLine("Will End soon!");
                    Thread.Sleep(500000000);
    
                }
                catch (Exception ex)
                {
                    Console.WriteLine(string.Format("Time {0}:{1}",DateTime.Now, ex.Message));
                    Thread.Sleep(500000000);
                }
            }
    
            private static void WriteLog(string userName, CancellationToken ct)
            {
                Console.WriteLine(string.Format("Begin Time {0}:ProcessId {2} ThreadId {3} {1}", DateTime.Now, userName, System.Diagnostics.Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId));
                if (userName != "LoadTest1" && userName != "LoadTest2" && userName != "LoadTest3")
                {
                    Thread.Sleep(5000);
                }
                if (ct.IsCancellationRequested)
                {
                    Console.WriteLine(string.Format("Cancel :{0} ThreadId {1}", userName, Thread.CurrentThread.ManagedThreadId));
                    ct.ThrowIfCancellationRequested();
                }
                Console.WriteLine(string.Format("End Time {0}:ProcessId {2} ThreadId {3} {1}", DateTime.Now, userName, System.Diagnostics.Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId));
            }


    5.总共10个任务,每次最多3个任务,每当这3个任务中任何一个完成,就会从后续任务中拿出任务来做
    static void Main(string[] args)
            {
                try
                {
                    int numberOfUsers = 10;
                    var users = new string[numberOfUsers];
                    for (int i = 0; i < numberOfUsers; i++)
                    {
                        users[i] = string.Format("LoadTest{0}", i + 1);
                    }
    
                    Action[] aArr = new Action[numberOfUsers];
                    int j = 0 ;
                    for (int i = 0; i < numberOfUsers; i++){
                    aArr[i] = new Action(() => WriteLog(users[j++]));
                   }
    
                    System.Threading.Tasks.ParallelOptions po = new ParallelOptions();
                    po.MaxDegreeOfParallelism = 3;
                    
                    try
                    {
                        System.Threading.Tasks.Parallel.Invoke(po, aArr);
                    }
                    catch (AggregateException e)
                    {
                        foreach (var v in e.InnerExceptions)
                        {
                            if (v is TaskCanceledException)
                                Console.WriteLine("   TaskCanceledException: Task {0}",
                                                  ((TaskCanceledException)v).Task.Id);
                            else
                                Console.WriteLine("   Exception: {0}", v.Message);
                        } 
    
                    }
                    Console.WriteLine("Will End soon!");
                    Thread.Sleep(500000000);
    
                }
                catch (Exception ex)
                {
                    Console.WriteLine(string.Format("Time {0}:{1}",DateTime.Now, ex.Message));
                    Thread.Sleep(500000000);
                }
            }


     

    6.总共10个任务,每次最多3个任务,而且每次必须3个一起开始
    static void Main(string[] args)
            {
                try
                {
                    int numberOfUsers = 10;
                    int maxConcurrent = 3;
                    var users = new string[numberOfUsers];
                    for (int i = 0; i < numberOfUsers; i++)
                    {
                        users[i] = string.Format("LoadTest{0}", i + 1);
                    }
    
                    int itemProcessed = 0;
                    int loopCnt = 0;
                    do
                    {
                        List<Task> taskList = new List<Task>();
                        for (int i = 0; i < maxConcurrent; i++)
                        {
                            taskList.Add(Task.Factory.StartNew((object obj) => 
                                {
                                    int j = (int)obj;
                                    try
                                    {
                                        if (loopCnt * maxConcurrent + j < numberOfUsers)
                                        {
                                            WriteLog(users[loopCnt * maxConcurrent + j]);
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.WriteLine(string.Format("{0} encounter error :{1}", users[loopCnt * maxConcurrent + j],ex.Message ));
                                    }
                                }
                                ,i));
                            Interlocked.Increment(ref itemProcessed);
                        }
                        Task.WaitAll(taskList.ToArray());
                        loopCnt++;
                    } while (itemProcessed < numberOfUsers);
    
                    Console.WriteLine("Will End soon!");
                    Thread.Sleep(500000000);
    
                }
                catch (Exception ex)
                {
                    Console.WriteLine(string.Format("Time {0}:{1}",DateTime.Now, ex.Message));
                    Thread.Sleep(500000000);
                }
            }


    7.每次最多3个user一起干活
    !wrong

    static void Main(string[] args)
            {
                
                ThreadPool.SetMaxThreads(1, 100);
    
                int numberOfUsers = 10;
                int maxWorkUsers = 3;
                var users = new string[numberOfUsers];
                for (int i = 0; i < numberOfUsers; i++)
                {
                    users[i] = string.Format("LoadTest{0}", i + 1);
                }
    
                var options = new ParallelOptions();
                options.MaxDegreeOfParallelism = maxWorkUsers;
                Parallel.ForEach(users, options,
                  (user) =>
                  {
                      WriteLog(user);
                  });
               Thread.Sleep(500000000);
            }

    correct

    static void Main(string[] args)
            {
                try
                {
                    int numberOfUsers = 10;
                    var users = new string[numberOfUsers];
                    for (int i = 0; i < numberOfUsers; i++)
                    {
                        users[i] = string.Format("LoadTest{0}", i + 1);
                    }
    
                    Action[] aArr = new Action[numberOfUsers];
                    int j = 0 ;
                    for (int i = 0; i < numberOfUsers; i++){
                    aArr[i] = new Action(() => WriteLog(users[j++]));
                   }
    
                    System.Threading.Tasks.ParallelOptions po = new ParallelOptions();
                    po.MaxDegreeOfParallelism = 3;
                    
                    try
                    {
                        System.Threading.Tasks.Parallel.Invoke(po, aArr);
                    }
                    catch (AggregateException e)
                    {
                        foreach (var v in e.InnerExceptions)
                        {
                            if (v is TaskCanceledException)
                                Console.WriteLine("   TaskCanceledException: Task {0}",
                                                  ((TaskCanceledException)v).Task.Id);
                            else
                                Console.WriteLine("   Exception: {0}", v.Message);
                        } 
    
                    }
                    Console.WriteLine("Will End soon!");
                    Thread.Sleep(500000000);
    
                }
                catch (Exception ex)
                {
                    Console.WriteLine(string.Format("Time {0}:{1}",DateTime.Now, ex.Message));
                    Thread.Sleep(500000000);
                }
            }
    
            private static void WriteLog(string userName)
            {
                Console.WriteLine(string.Format("Begin Time {0}:ProcessId {2} ThreadId {3} {1}", DateTime.Now, userName, System.Diagnostics.Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId));
                Thread.Sleep(5000);
                if (userName == "LoadTest2")
                {
                    Thread.Sleep(5000);
                    throw new Exception("Lazy!");
                }
                Console.WriteLine(string.Format("End Time {0}:ProcessId {2} ThreadId {3} {1}", DateTime.Now, userName, System.Diagnostics.Process.GetCurrentProcess().Id, Thread.CurrentThread.ManagedThreadId));
            }


    8.多線程改變某值

    private static List<string> testList = new List<string>();
            private static void AddList(string name)
            {
                testList.Add(name);
            }
    
            static void test2()
            {
                
                int threadcount = 10;
                List<Thread> threads = new List<Thread>();
                for (int i = 0; i < threadcount; i++)
                {
                    Thread t = new Thread(delegate(object parameter)
                    {
                        EmpServiceDataContext db = new EmpServiceDataContext();
                        int _i = (int)parameter;
                        int index = 0;
                        for( int k = 0 ; k < 20000 ; k++)
                        {
                            if (index % threadcount == _i)
                            {
                                try
                                {
                                    AddList("Thread" + k);
                                }
                                catch (Exception ex)
                                {
                                }
                            }
                            index++;
                        }
                    });
                    t.Name = string.Format("SendEmailThread_{0}", i);
                    threads.Add(t);
                    t.Start(i);
                }
                foreach (Thread t in threads)
                {
                    t.Join();
                }
            }
            
    Task t = Task.Factory.StartNew(() => test2());
    t.Wait();


    9.volatile  和 Interlocked
    http://baike.baidu.com/view/608706.htm?fr=aladdin

    1). 并行设备的硬件寄存器(如:状态寄存器)
     
    2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
     
    3). 多线程应用中被几个任务共享的变量

    Interlocked.Decrement(ref JOB_COUNT);


    10. ThreadStartStop
    如何:创建和终止线程(C# 编程指南)
    http://msdn.microsoft.com/zh-cn/library/7a2f3ay4(VS.80).aspx

    public class Worker
    {
        // This method will be called when the thread is started.
        public void DoWork()
        {
            while (!_shouldStop)
            {
                Console.WriteLine("worker thread: working...");
            }
            Console.WriteLine("worker thread: terminating gracefully.");
        }
        public void RequestStop()
        {
            _shouldStop = true;
        }
        // Volatile is used as hint to the compiler that this data
        // member will be accessed by multiple threads.
        private volatile bool _shouldStop;
    }
    
    public class WorkerThreadExample
    {
        static void Main()
        {
            // Create the thread object. This does not start the thread.
            Worker workerObject = new Worker();
            Thread workerThread = new Thread(workerObject.DoWork);
    
            // Start the worker thread.
            workerThread.Start();
            Console.WriteLine("main thread: Starting worker thread...");
    
            // Loop until worker thread activates.
            while (!workerThread.IsAlive);
    
            // Put the main thread to sleep for 1 millisecond to
            // allow the worker thread to do some work:
            Thread.Sleep(1);
    
            // Request that the worker thread stop itself:
            workerObject.RequestStop();
    
            // Use the Join method to block the current thread 
            // until the object's thread terminates.
            workerThread.Join();
            Console.WriteLine("main thread: Worker thread has terminated.");
        }
    }
    



     

  • 相关阅读:
    均值回归理论,均值回归法则是指万物最终都将回归于其长期的均值
    文本框仅允许输入大于0的正整数
    Angularjs接收服务端的布尔值
    Ajax POST单个对象或多个对象至API
    ASP.NET MVC程序重构
    查询数据库创建时间
    查询MS SQL的版本号
    获取Data和Log默认路径
    快速查找对象
    表关联使用INNER JOIN实现更新功能
  • 原文地址:https://www.cnblogs.com/sui84/p/6777090.html
Copyright © 2011-2022 走看看