任务线程和同步

Posted liuslayer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了任务线程和同步相关的知识,希望对你有一定的参考价值。

BarrierSample

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Wrox.ProCSharp.Threading
{
    class Program
    {
        static void Main()
        {
            const int numberTasks = 2;
            const int partitionSize = 1000000;
            var data = new List<string>(FillData(partitionSize * numberTasks));

            var barrier = new Barrier(numberTasks + 1);

            var tasks = new Task<int[]>[numberTasks];
            for (int i = 0; i < numberTasks; i++)
            {
                //tasks[i] = taskFactory.StartNew<int[]>(CalculationInTask,
                //    Tuple.Create(i, partitionSize, barrier, data));
                int jobNumber = i;
                tasks[i] = Task.Run(() => CalculationInTask(jobNumber, partitionSize, barrier, data));
            }

            barrier.SignalAndWait();
            var resultCollection = tasks[0].Result.Zip(tasks[1].Result, (c1, c2) =>
                {
                    return c1 + c2;
                });

            char ch = a;
            int sum = 0;
            foreach (var x in resultCollection)
            {
                Console.WriteLine("{0}, count: {1}", ch++, x);
                sum += x;
            }

            Console.WriteLine("main finished {0}", sum);
            Console.WriteLine("remaining {0}, phase {1}", barrier.ParticipantsRemaining, barrier.CurrentPhaseNumber);

        }

//        static int[] CalculationInTask(object p)
        static int[] CalculationInTask(int jobNumber, int partitionSize, Barrier barrier, IList<string> coll)
        {
            var data = new List<string>(coll);
            int start = jobNumber * partitionSize;
            int end = start + partitionSize;
            Console.WriteLine("Task {0}: partition from {1} to {2}", Task.CurrentId, start, end);
            int[] charCount = new int[26];
            for (int j = start; j < end; j++)
            {
                char c = data[j][0];
                charCount[c - 97]++;
            }
            Console.WriteLine("Calculation completed from task {0}. {1} times a, {2} times z", Task.CurrentId, charCount[0], charCount[25]);

            barrier.RemoveParticipant();
            Console.WriteLine("Task {0} removed from barrier, remaining participants {1}", Task.CurrentId, barrier.ParticipantsRemaining);
            return charCount;
        }

        public static IEnumerable<string> FillData(int size)
        {
            var data = new List<string>(size);
            var r = new Random();
            for (int i = 0; i < size; i++)
            {
                data.Add(GetString(r));
            }
            return data;
        }
        private static string GetString(Random r)
        {
            var sb = new StringBuilder(6);
            for (int i = 0; i < 6; i++)
            {
                sb.Append((char)(r.Next(26) + 97));
            }
            return sb.ToString();
        }
    }
}
View Code

CancellationSamples

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Wrox.ProCSharp.Threading
{

  class Program
  {
    static void Main()
    {
      // CancelParallelLoop();
      CancelTask();
      Console.ReadLine();
    }

    static void CancelParallelLoop()
    {
      var cts = new CancellationTokenSource();
      cts.Token.ThrowIfCancellationRequested();
      cts.Token.Register(() => Console.WriteLine("** token cancelled"));

      // start a task that sends a cancel after 500 ms      
      cts.CancelAfter(500);

      try
      {
        ParallelLoopResult result =
           Parallel.For(0, 100,
               new ParallelOptions()
               {
                 CancellationToken = cts.Token
               },
               x =>
               {
                 Console.WriteLine("loop {0} started", x);
                 int sum = 0;
                 for (int i = 0; i < 100; i++)
                 {
                   Thread.Sleep(2);
                   sum += i;
                 }
                 Console.WriteLine("loop {0} finished", x);
               });
      }
      catch (OperationCanceledException ex)
      {
        Console.WriteLine(ex.Message);
      }
    }

    static void CancelTask()
    {
      var cts = new CancellationTokenSource();
      cts.Token.Register(() => Console.WriteLine("*** task cancelled"));

      // send a cancel after 500 ms
      cts.CancelAfter(500);

      Task t1 = Task.Run(() =>
        {
          Console.WriteLine("in task");
          for (int i = 0; i < 20; i++)
          {
            Thread.Sleep(100);
            CancellationToken token = cts.Token;
            if (token.IsCancellationRequested)
            {
              Console.WriteLine("cancelling was requested, cancelling from within the task");
              token.ThrowIfCancellationRequested();
              break;
            }
            Console.WriteLine("in loop");
          }
          Console.WriteLine("task finished without cancellation");
        }, cts.Token);

      try
      {
        t1.Wait();
      }
      catch (AggregateException ex)
      {
        Console.WriteLine("exception: {0}, {1}", ex.GetType().Name, ex.Message);
        foreach (var innerException in ex.InnerExceptions)
        {
          Console.WriteLine("inner excepion: {0}, {1}", ex.InnerException.GetType().Name, ex.InnerException.Message);
        }
      }

    }
  }
}
View Code

DataFlowSample

技术分享
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;

namespace DataFlowSample
{
  class Program
  {
    static void Main()
    {
      // ActionBlockSample();
      // SourceAndTargetBlocksSample();

      var target = SetupPipeline();
      target.Post("../..");
      Console.ReadLine();
    }

    private static void ActionBlockSample()
    {
      var processInput = new ActionBlock<string>(s =>
      {
        Console.WriteLine("user input: {0}", s);
      });

      bool exit = false;
      while (!exit)
      {
        string input = Console.ReadLine();
        if (string.Compare(input, "exit", ignoreCase: true) == 0)
        {
          exit = true;
        }
        else
        {
          processInput.Post(input);
        }
      }
    }

    private static void SourceAndTargetBlocksSample()
    {
      Task t1 = Task.Run(() => Producer());
      Task t2 = Task.Run(() => Consumer());
      Task.WaitAll(t1, t2);
    }

    static BufferBlock<string> buffer = new BufferBlock<string>();

    static void Producer()
    {
      bool exit = false;
      while (!exit)
      {
        string input = Console.ReadLine();
        if (string.Compare(input, "exit", ignoreCase: true) == 0)
        {
          exit = true;
        }
        else
        {
          buffer.Post(input);
        }
      }
    }

    static async void Consumer()
    {
      while (true)
      {
        string data = await buffer.ReceiveAsync();

        Console.WriteLine("user input: {0}", data);
      }
    }



    static ITargetBlock<string> SetupPipeline()
    {

      var fileNames = new TransformBlock<string, IEnumerable<string>>(path =>
      {
        try
        {
          return GetFileNames(path);
        }
        catch (OperationCanceledException)
        {
          return Enumerable.Empty<string>();
        }
      });

      var lines = new TransformBlock<IEnumerable<string>, IEnumerable<string>>(input =>
          {
            try
            {
              return LoadLines(input);
            }
            catch (OperationCanceledException)
            {
              return Enumerable.Empty<string>();
            }
          });

      var words = new TransformBlock<IEnumerable<string>, IEnumerable<string>>(lines2 =>
      {
        return GetWords(lines2);
      });

      var display = new ActionBlock<IEnumerable<string>>(coll =>
      {
        foreach (var s in coll)
        {
          Console.WriteLine(s);
        }
      });

      fileNames.LinkTo(lines);
      lines.LinkTo(words);
      words.LinkTo(display);
      // fileNames.LinkTo(loadLines, fn => fn.Count() > 0);

      return fileNames;
    }

    static IEnumerable<string> GetWords(IEnumerable<string> lines)
    {
      foreach (var line in lines)
      {
        string[] words = line.Split( , ;, (, ), {, }, ., ,);
        foreach (var word in words)
        {
          if (!string.IsNullOrEmpty(word))
          {
            yield return word;
          }
        }
      }
    }

    static IEnumerable<string> LoadLines(IEnumerable<string> fileNames)
    {
      foreach (var fileName in fileNames)
      {
        using (FileStream stream = File.OpenRead(fileName))
        {
          var reader = new StreamReader(stream);
          string line = null;
          while ((line = reader.ReadLine()) != null)
          {
            // Console.WriteLine("LoadLines {0}", line);
            yield return line;
          }
        }
      }
    }

    static IEnumerable<string> GetFileNames(string path)
    {
      foreach (var fileName in Directory.EnumerateFiles(path, "*.cs"))
      {
        Console.WriteLine("GetFileNames {0}", fileName);
        yield return fileName;
      }
    }
  }
}
View Code

EventSample

技术分享
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Wrox.ProCSharp.Threading
{
  public class Calculator
  {
    private ManualResetEventSlim mEvent;
    private CountdownEvent cEvent;

    public int Result { get; private set; }

    public Calculator(ManualResetEventSlim ev)
    {
      this.mEvent = ev;
    }
    public Calculator(CountdownEvent ev)
    {
      this.cEvent = ev;
    }

    public void Calculation(int x, int y)
    {
      Console.WriteLine("Task {0} starts calculation", Task.CurrentId);
      Thread.Sleep(new Random().Next(3000));
      Result = x + y;

      // signal the event—completed!
      Console.WriteLine("Task {0} is ready", Task.CurrentId);
      mEvent.Set();
      // cEvent.Signal();
    }
  }

}
View Code
技术分享
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Wrox.ProCSharp.Threading
{
  class Program
  {
    static void Main()
    {
      const int taskCount = 4;

      var mEvents = new ManualResetEventSlim[taskCount];
      // var cEvent = new CountdownEvent(taskCount);

      var waitHandles = new WaitHandle[taskCount];
      var calcs = new Calculator[taskCount];

      for (int i = 0; i < taskCount; i++)
      {
        int i1 = i;
        mEvents[i] = new ManualResetEventSlim(false);
        waitHandles[i] = mEvents[i].WaitHandle;
        calcs[i] = new Calculator(mEvents[i]);
        //calcs[i] = new Calculator(cEvent);

        Task.Run(() => calcs[i1].Calculation(i1 + 1, i1 + 3));

      }

      //cEvent.Wait();
      //Console.WriteLine("all finished");
      //for (int i = 0; i < taskCount; i++)
      //{
      //    Console.WriteLine("task for {0}, result: {1}", i, calcs[i].Result);
      //}

      for (int i = 0; i < taskCount; i++)
      {
        int index = WaitHandle.WaitAny(waitHandles);
        if (index == WaitHandle.WaitTimeout)
        {
          Console.WriteLine("Timeout!!");
        }
        else
        {
          mEvents[index].Reset();
          Console.WriteLine("finished task for {0}, result: {1}",
                            index, calcs[index].Result);
        }
      }

    }
  }
}
View Code

ParallelSamples

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Wrox.ProCSharp.Threading
{
  class Program
  {
    static void Main()
    {
      // ParallelFor();
      // ParallelForeach();
      ParallelInvoke();
      Console.ReadLine();
    }

    static void ParallelInvoke()
    {
      Parallel.Invoke(Foo, Bar);
    }

    static void Foo()
    {
      Console.WriteLine("foo");
    }

    static void Bar()
    {
      Console.WriteLine("bar");
    }

    static void ParallelForeach()
    {
      string[] data = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve" };

      ParallelLoopResult result =
          Parallel.ForEach<string>(data, s =>
              {
                Console.WriteLine(s);
              });


      Parallel.ForEach<string>(data,
          (s, pls, l) =>
          {
            Console.WriteLine("{0} {1}", s, l);

          });

    }

    static void ParallelFor()
    {
      //// simple scenario
      //ParallelLoopResult result =
      //    Parallel.For(0, 10, async i =>
      //        {
      //          Console.WriteLine("{0}, task: {1}, thread: {2}", i,
      //             Task.CurrentId, Thread.CurrentThread.ManagedThreadId);

      //          await Task.Delay(10);
      //          Console.WriteLine("{0}, task: {1}, thread: {2}", i,
      //            Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
      //        });
      //Console.WriteLine("is completed: {0}", result.IsCompleted);

      // breaking early
      //ParallelLoopResult result =
      //    Parallel.For(10, 40, (int i, ParallelLoopState pls) =>
      //        {
      //          Console.WriteLine("i: {0} task {1}", i, Task.CurrentId);
      //          Thread.Sleep(10);
      //          if (i > 15)
      //            pls.Break();
      //        });
      //Console.WriteLine("Is completed: {0}", result.IsCompleted);
      //if (!result.IsCompleted)
      //  Console.WriteLine("lowest break iteration: {0}", result.LowestBreakIteration);


      Parallel.For<string>(0, 20, () =>
        {
          // invoked once for each thread
          Console.WriteLine("init thread {0}, task {1}", Thread.CurrentThread.ManagedThreadId, Task.CurrentId);
          return String.Format("t{0}", Thread.CurrentThread.ManagedThreadId);
        },
        (i, pls, str1) =>
        {
          // invoked for each member
          Console.WriteLine("body i {0} str1 {1} thread {2} task {3}", i, str1,
              Thread.CurrentThread.ManagedThreadId,
              Task.CurrentId);
          Thread.Sleep(10);
          return String.Format("i {0}", i);
        },
        (str1) =>
        {
          // final action on each thread
          Console.WriteLine("finally {0}", str1);
        });
    }
  }
}
View Code

ReaderWriterSample

技术分享
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Wrox.ProCSharp.Threading
{
    class Program
    {
        private static List<int> items = new List<int>() { 0, 1, 2, 3, 4, 5 };
        private static ReaderWriterLockSlim rwl = new
              ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

        static void ReaderMethod(object reader)
        {
            try
            {
                rwl.EnterReadLock();

                for (int i = 0; i < items.Count; i++)
                {
                    Console.WriteLine("reader {0}, loop: {1}, item: {2}",
                          reader, i, items[i]);
                    Thread.Sleep(40);
                }
            }
            finally
            {
                rwl.ExitReadLock();
            }
        }

        static void WriterMethod(object writer)
        {
            try
            {
                while (!rwl.TryEnterWriteLock(50))
                {
                    Console.WriteLine("Writer {0} waiting for the write lock",
                          writer);
                    Console.WriteLine("current reader count: {0}",
                          rwl.CurrentReadCount);
                }
                Console.WriteLine("Writer {0} acquired the lock", writer);
                for (int i = 0; i < items.Count; i++)
                {
                    items[i]++;
                    Thread.Sleep(50);
                }
                Console.WriteLine("Writer {0} finished", writer);
            }
            finally
            {
                rwl.ExitWriteLock();
            }
        }

        static void Main()
        {
            var taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);
            var tasks = new Task[6];
            tasks[0] = taskFactory.StartNew(WriterMethod, 1);
            tasks[1] = taskFactory.StartNew(ReaderMethod, 1);
            tasks[2] = taskFactory.StartNew(ReaderMethod, 2);
            tasks[3] = taskFactory.StartNew(WriterMethod, 2);
            tasks[4] = taskFactory.StartNew(ReaderMethod, 3);
            tasks[5] = taskFactory.StartNew(ReaderMethod, 4);

            for (int i = 0; i < 6; i++)
            {
                tasks[i].Wait();
            }
        }
    }

}
View Code

SemaphoreSample

技术分享
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Wrox.ProCSharp.Threading
{
  class Program
  {
    static void Main()
    {
      int taskCount = 6;
      int semaphoreCount = 3;
      var semaphore = new SemaphoreSlim(semaphoreCount, semaphoreCount);
      var tasks = new Task[taskCount];

      for (int i = 0; i < taskCount; i++)
      {
        tasks[i] = Task.Run(() => TaskMain(semaphore));
      }

      Task.WaitAll(tasks);

      Console.WriteLine("All tasks finished");
    }


    static void TaskMain(SemaphoreSlim semaphore)
    {
      bool isCompleted = false;
      while (!isCompleted)
      {
        if (semaphore.Wait(600))
        {
          try
          {
            Console.WriteLine("Task {0} locks the semaphore", Task.CurrentId);
            Thread.Sleep(2000);
          }
          finally
          {
            Console.WriteLine("Task {0} releases the semaphore", Task.CurrentId);
            semaphore.Release();
            isCompleted = true;
          }
        }
        else
        {
          Console.WriteLine("Timeout for task {0}; wait again",
             Task.CurrentId);
        }
      }
    }
  }
}
View Code

SynchronizationSamples

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Wrox.ProCSharp.Threading
{
    public class Job
    {
        SharedState sharedState;
        public Job(SharedState sharedState)
        {
            this.sharedState = sharedState;
        }
        public void DoTheJob()
        {
            for (int i = 0; i < 50000; i++)
            {
                // lock (sharedState)
                {
                    sharedState.State += 1;
                    //   sharedState.IncrementState();
                }
            }

        }
    }
}
View Code
技术分享
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Wrox.ProCSharp.Threading
{

  class Program
  {
    static void Main()
    {
      for (int i = 0; i < 5; i++)
      {
        SyncSample();
      }

    }

    static void SyncSample()
    {
      object obj = new object();
      bool lockTaken = false;
      Monitor.TryEnter(obj, 500, ref lockTaken);
      if (lockTaken)
      {
        try
        {
          // acquired the lock
          // synchronized region for obj
        }
        finally
        {
          Monitor.Exit(obj);
        }

      }
      else
      {
        // didn‘t get the lock, do something else
      }

      int numTasks = 20;
      var state = new SharedState();
      var tasks = new Task[numTasks];

      for (int i = 0; i < numTasks; i++)
      {
        tasks[i] = Task.Run(() => new Job(state).DoTheJob());
      }

      for (int i = 0; i < numTasks; i++)
      {
        tasks[i].Wait();
      }

      Console.WriteLine("summarized {0}", state.State);
    }
  }
}
View Code
技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Wrox.ProCSharp.Threading
{
    public class SharedState
    {
        private int state = 0;

        public int State { get; set; }


        public int IncrementState()
        {
            //  lock (this)
            {
                return ++state;
            }
            // return Interlocked.Increment(ref state);
        }

    }
}
View Code

TaskSamples

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.IO;

namespace TaskSamples
{
  class Program
  {
      static void Main()
      {
           //ParallelDemo();

          //1、创建任务的几种方法
          //TasksUsingThreadPool();

          //2、同步任务,任务可以同步运行,以相同的线程作为主调线程
          // RunSynchronousTask();

          //3、使用单独线程的任务,创建一个长时间运行的任务
          // LongRunningTask();

          //任务的结果,返回某个结果的任务
          // ResultsFromTasks();

          //连续的任务
          // ContinuationTask();

          //任务层次结构
          ParentAndChild();

          // HierarchyTasks("c:\\");


          Console.ReadLine();
      }

    private static void RunSynchronousTask()
    {
      TaskMethod("just the main thread");
      var t1 = new Task(TaskMethod, "run sync");
      t1.RunSynchronously();
    }

    private static void LongRunningTask()
    {
      var t1 = new Task(TaskMethod, "long running", TaskCreationOptions.LongRunning);
      t1.Start();
    }

    static void ResultsFromTasks()
    {
      var t1 = new Task<Tuple<int, int>>(TaskWithResult, Tuple.Create<int, int>(8, 3));
      t1.Start();
      Console.WriteLine(t1.Result);
      t1.Wait();
      Console.WriteLine("result from task: {0} {1}", t1.Result.Item1, t1.Result.Item2);
    }

    static Tuple<int, int> TaskWithResult(object division)
    {
        Tuple<int, int> div = (Tuple<int, int>)division;
        int result = div.Item1 / div.Item2;
        int reminder = div.Item1 % div.Item2;
        Console.WriteLine("task creates a result...");

        return Tuple.Create<int, int>(result, reminder);
    }

    static void TasksUsingThreadPool()
    {
      var tf = new TaskFactory();
      Task t1 = tf.StartNew(TaskMethod, "using a task factory");

      Task t2 = Task.Factory.StartNew(TaskMethod, "factory via a task");

      var t3 = new Task(TaskMethod, "using a task constructor and Start");
      t3.Start();

      Task t4 = Task.Run(() => TaskMethod("using the Run method"));

    }

    static void ContinuationTask()
    {
      Task t1 = new Task(DoOnFirst);
      Task t2 = t1.ContinueWith(DoOnSecond);
      Task t3 = t1.ContinueWith(DoOnSecond);
      Task t4 = t2.ContinueWith(DoOnSecond);
      Task t5 = t1.ContinueWith(DoOnError, TaskContinuationOptions.OnlyOnFaulted);
      t1.Start();


      Thread.Sleep(5000);

    }


    static void DoOnFirst()
    {
      Console.WriteLine("doing some task {0}", Task.CurrentId);
      Thread.Sleep(3000);
    }

    static void DoOnSecond(Task t)
    {
      Console.WriteLine("task {0} finished", t.Id);
      Console.WriteLine("this task id {0}", Task.CurrentId);
      Console.WriteLine("do some cleanup");
      Thread.Sleep(3000);
    }

    static void DoOnError(Task t)
    {
      Console.WriteLine("task {0} had an error!", t.Id);
      Console.WriteLine("my id {0}", Task.CurrentId);
      Console.WriteLine("do some cleanup");
    }

    static void ParentAndChild()
    {
      var parent = new Task(ParentTask);
      parent.Start();
      Thread.Sleep(2000);
      Console.WriteLine(parent.Status);
      Thread.Sleep(4000);
      Console.WriteLine(parent.Status);

    }
    static void ParentTask()
    {
      Console.WriteLine("task id {0}", Task.CurrentId);
      var child = new Task(ChildTask,TaskCreationOptions.AttachedToParent); // , TaskCreationOptions.DetachedFromParent);
      child.Start();
      Thread.Sleep(1000);
      Console.WriteLine("parent started child");
      // Thread.Sleep(3000);
    }
    static void ChildTask()
    {
      // Console.WriteLine("task id {0}, parent: {1}", Task.Current.Id, Task.Current.Parent.Id);
      Console.WriteLine("child");
      Thread.Sleep(5000);
      Console.WriteLine("child finished");
    }

    static object taskMethodLock = new object();
    static void TaskMethod(object title)
    {
      lock (taskMethodLock)
      {
        Console.WriteLine(title);
        Console.WriteLine("Task id: {0}, thread: {1}",
          Task.CurrentId == null ? "no task" : Task.CurrentId.ToString(),
          Thread.CurrentThread.ManagedThreadId);
        Console.WriteLine("is pooled thread: {0}", Thread.CurrentThread.IsThreadPoolThread);
        Console.WriteLine("is background thread: {0}", Thread.CurrentThread.IsBackground);
        Console.WriteLine();
      }
    }

    static void ParallelDemo()
    {
      // Parallel.For(0, 5, i => Console.WriteLine(i));
      Parallel.For<string>(0, 20, () => "abcd",
          (x, ls, str) =>
          {
            Console.WriteLine(x);
            return "defg";
          },
              (str) =>
              {
                Console.WriteLine("action {0}", str);
              });

      ParallelOptions po = new ParallelOptions();




    }



    //static void ParentAndChild()
    //{
    //    TaskFactory factory = new TaskFactory();
    //    var t1 = factory.StartNew(() =>
    //        {
    //            Console.WriteLine("parent task {0}", Task.CurrentId);

    //            factory.StartNew(() =>
    //                {
    //                    Console.WriteLine("child task {0}", Task.CurrentId);
    //                    Thread.Sleep(2000);
    //                    Console.WriteLine("finished child");
    //                }, TaskCreationOptions.AttachedToParent);

    //            Console.WriteLine("finished parent");
    //        });

    //    t1.Wait();

    //}


  }
}
View Code

ThreadingIssues

技术分享
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;


namespace Wrox.ProCSharp.Threading
{
  class Program
  {
    static void Main()
    {
      // RaceConditions();
      Deadlock();

      Console.ReadLine();

    }

    static void RaceConditions()
    {
      var state = new StateObject();
      for (int i = 0; i < 2; i++)
      {
        Task.Run(() => new SampleTask().RaceCondition(state));
      }
    }

    static void Deadlock()
    {
      var s1 = new StateObject();
      var s2 = new StateObject();
      Task.Run(() => new SampleTask(s1, s2).Deadlock1());
      Task.Run(() => new SampleTask(s1, s2).Deadlock2());

      Thread.Sleep(100000);
    }
  }
}
View Code
技术分享
using System;
using System.Diagnostics;
using System.Threading;

namespace Wrox.ProCSharp.Threading
{

    public class StateObject
    {
        private int state = 5;
        private object sync = new object();

        public void ChangeState(int loop)
        {
//            lock (sync)
            {
                if (state == 5)
                {
                    state++;
                    Trace.Assert(state == 6, "Race condition occurred after " + loop + " loops");
                }
                state = 5;
            }
        }
    }

    public class SampleTask
    {
        //internal static int a;
        //private static Object sync = new object();

        public SampleTask()
        {

        }

        public void RaceCondition(object o)
        {
            Trace.Assert(o is StateObject, "o must be of type StateObject");
            StateObject state = o as StateObject;

            int i = 0;
            while (true)
            {
                // lock (state) // no race condition with this lock
                {
                    state.ChangeState(i++);
                }
            }

        }

        public SampleTask(StateObject s1, StateObject s2)
        {
            this.s1 = s1;
            this.s2 = s2;
        }

        StateObject s1;
        StateObject s2;


        public void Deadlock1()
        {
            int i = 0;
            while (true)
            {
                lock (s1)
                {
                    lock (s2)
                    {
                        s1.ChangeState(i);
                        s2.ChangeState(i++);
                        Console.WriteLine("still running, {0}", i);
                    }
                }
            }

        }

        public void Deadlock2()
        {
            int i = 0;
            while (true)
            {
                lock (s2)
                {
                    lock (s1)
                    {
                        s1.ChangeState(i);
                        s2.ChangeState(i++);
                        Console.WriteLine("still running, {0}", i);
                    }
                }
            }
        }

    }
}
View Code

ThreadPoolSamples

技术分享
using System;
using System.Threading;

namespace Wrox.ProCSharp.Threading
{


    class Program
    {
        static void Main()
        {
            int nWorkerThreads;
            int nCompletionPortThreads;
            ThreadPool.GetMaxThreads(out nWorkerThreads, out nCompletionPortThreads);
            Console.WriteLine("Max worker threads: {0}, I/O completion threads: {1}", nWorkerThreads, nCompletionPortThreads);

            for (int i = 0; i < 5; i++)
            {
                ThreadPool.QueueUserWorkItem(JobForAThread);

            }

            Thread.Sleep(3000);
            Console.ReadLine();
        }


        static void JobForAThread(object state)
        {
            for (int i = 0; i < 3; i++)
            {
                Console.WriteLine("loop {0}, running inside pooled thread {1}", i,
                   Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(50);
            }

        }
    }
}
View Code

ThreadSamples

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Wrox.ProCSharp.Threading
{
    public class MyThread
    {
        private string data;

        public MyThread(string data)
        {
            this.data = data;
        }

        public void ThreadMain()
        {
            Console.WriteLine("Running in a thread, data: {0}", data);
        }
    }



    public struct Data
    {
        public string Message;
    }


    class Program
    {
        static void Main()
        {
            FirstThread();

            //var t1 = new Thread(Prio);
            //t1.Name = "First";

            //var t2 = new Thread(Prio);
            //t2.Name = "Second";
            //t1.Priority = ThreadPriority.Highest;
            //t2.Priority = ThreadPriority.Lowest;

            //t1.Start();
            //t2.Start();

            //var t1 = new Thread(ThreadMain);
            //t1.Name = "MyNewThread1";
            //t1.IsBackground = true;
            //t1.Start();
            //Console.WriteLine("Main thread ending now...");

            //var d = new Data { Message = "Info" };
            //var t2 = new Thread(ThreadMainWithParameters);
            //t2.Start(d);

            //var obj = new MyThread("info");
            //var t3 = new Thread(obj.ThreadMain);
            //t3.Start();
        }

        static void Prio()
        {
            for (int i = 0; i < 10000; i++)
            {
                Console.WriteLine("{0}, {1}", Thread.CurrentThread.Name, i);
            }
        }

        static void ThreadMain()
        {
            Console.WriteLine("Thread {0} started", Thread.CurrentThread.Name);
            Thread.Sleep(3000);
            // Console.WriteLine("Running in the thread {0}, id: {1}.", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("Thread {0} completed", Thread.CurrentThread.Name);
        }

        static void ThreadMainWithParameters(object o)
        {
            Data d = (Data)o;
            Console.WriteLine("Running in a thread, received {0}", d.Message);
        }

        static void FirstThread()
        {
            new Thread(() => Console.WriteLine("Running in a thread, id: {0}", Thread.CurrentThread.ManagedThreadId)).Start();

            Console.WriteLine("This is the main thread, id: {0}", Thread.CurrentThread.ManagedThreadId);
        }
    }
}
View Code

TimerSample

技术分享
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Wrox.ProCSharp.Threading
{

    class Program
    {
        private static void ThreadingTimer()
        {
            using (var t1 = new System.Threading.Timer(
               TimeAction, null, TimeSpan.FromSeconds(2),
               TimeSpan.FromSeconds(3)))
            {
                
                Thread.Sleep(15000);
            }
            
        }

        static void TimeAction(object o)
        {
            Console.WriteLine("System.Threading.Timer {0:T}", DateTime.Now);
        }

        private static void TimersTimer()
        {
            var t1 = new System.Timers.Timer(1000);
            t1.AutoReset = true;
            t1.Elapsed += TimeAction;
            t1.Start();
            Thread.Sleep(10000);
            t1.Stop();

            t1.Dispose();
        }

        static void TimeAction(object sender, System.Timers.ElapsedEventArgs e)
        {
            Console.WriteLine("System.Timers.Timer {0:T}", e.SignalTime);
        }


        static void Main(string[] args)
        {
             //ThreadingTimer();
            TimersTimer();
        }
    }
}
View Code

 

以上是关于任务线程和同步的主要内容,如果未能解决你的问题,请参考以下文章

线程+任务+同步

同步/异步 异步回调 协成 线程队列

csharp 线程和异步任务片段

0182 JavaScript执行机制:单线程,同步任务和异步任务,执行栈,消息队列,事件循环

newCacheThreadPool()newFixedThreadPool()newScheduledThreadPool()newSingleThreadExecutor()自定义线程池(代码片段

线程同步-使用ReaderWriterLockSlim类