C#并发编制程序

最近看C#
并发编制程序··,那里做一下总计··拾二线程,异步,并行,大部分都以多年来看C#出现编制程序这些书提到到的··那里仅仅列出达成格局,书里头介绍的其余的事物没有涉嫌比如废除操作,同步操作,集合之类的东西

线程:Thread,ThreadPool,BackgroundWorker,

Thread
能够又越来越多控制··ThreadPool正是丢进来系统好管理线程,BackgroundWorker相当于加了风波的线程,用在thread执行函数里边加事件,外边注册加invoke就足以兑现类似backgroundworker的成效,

只是机制就如不太雷同,看了反编写翻译的方式invoke里边的代码
带了汪洋的非托管代码··看十分的小懂··,backgroundworker内部选拔委托的异步执行办法,就是begininvoke,
 C#的begininvoke内部贯彻类似正是102线程,通过联合上下文回到ui线程完毕类似invoke
的操作

thread
和threadpool都能够传递贰个委托进去,那样能够经过信托做一些优异操作··也可以一向定义个事件完成文告进程的功效

肆.5的async/await  里边iprogress也能兑现类似报告进度功效

 代码在winform窗体里边执行               
 private event EventHandler myevent;
//thread
                  myevent += delegate {
                      Invoke(new EventHandler(delegate {
                          Text = "threadtest";
                      }));
                  };
                  Action myaction = new Action(() => {
                      MessageBox.Show("delegatetest");
                  });
                  new Thread(new ParameterizedThreadStart((obj) =>
                  {
                      //dosomthing
                      Thread.Sleep(2000);
                      (obj as Action)();
                  })).Start(myaction);

                  new Thread(new ThreadStart(() =>
                  {
                      //dosomething
                      Thread.Sleep(2000);
                      myevent?.Invoke(null, new EventArgs());
                  })).Start();

                  //backgroundworker
                  BackgroundWorker worker = new BackgroundWorker();
                  worker.WorkerReportsProgress = true;
                  worker.DoWork += delegate {
                      //dosomething
                      Thread.Sleep(2000);
                      worker.ReportProgress(100);
                  };
                  worker.ProgressChanged += (send, stat) =>
                  {
                      Text = "doworker";
                  };
                  worker.RunWorkerAsync();

                  //threadpool
                  ThreadPool.QueueUserWorkItem(new WaitCallback((stat) => {
                      //dosomthing
                      Thread.Sleep(1000);

                  }));
                  //task 异步
                  Task t = new Task(() => {
                      //dosomething
                      Thread.Sleep(3000);

                  });
                  Action<Task> taction = new Action<Task>((tas) => {
                          Text = "Task";
                  });
                  var context = TaskScheduler.FromCurrentSynchronizationContext();//这里创建一个当前上下文的任务调度器,其实就是当前的ui线程上下文
                  t.ContinueWith(taction, context);//吧上边的调度器传入,接着的这个任务就会用这个调度器执行,内部其实就是post方法把操作放在当前ui线程进行同步执行,这样就不会报错了
                  t.Start();//这里是异步的方式,默认是以线程池的方式执行,如果在这里放入ui操作会报错线程间操作无效

事先的异步编制程序,通过beginInvoke
,委托和control都有周边措施,invoke正是同步施行,
begininvoke异步执行,那么些里面据悉也是用线程池完毕的异步

            Action act = new Action(() => {
                Thread.Sleep(2000);
                Console.WriteLine("121231");
            });
            var callback = new AsyncCallback((iasynccallback) =>
            {
                Console.WriteLine("OK");
            });
            var res=act.BeginInvoke(callback, null);
            Console.WriteLine("异步测试");
            act.EndInvoke(res);

上面有Task的写法,task通过职务调度器相当于TaskScheduler来完结调度,能够在时下线程执行,也足以经过线程池执行,这么些TaskScheduler
有三种达成,一种是用线程池达成,一种用上下文实现类似上面包车型地铁backgroundworker,

也便是SynchronizationContext那个类,那么些类又八个Post方法能够将异步的方法以共同的法子履行到钦赐的上下文中去,

而四.伍之中的async/await也是以看似的秘籍,又上下文这几个定义,这些async/await
花样可多了···那里就不多说了。。。

此间举个例子,能够把窗体时间一向定义为异步函数,这样事件措施里边用await去异步执行,而在章程中又能够一向刷新ui,上面的代码是能够运维成功的·
这几个完全颠覆了前边的写法··此前的要是要拓展异步,比如线程中要更新ui就要invoke不然肯定要报错,可能使用方面委托的异步执行通过回调函数的艺术去执行ui刷新应该也是要invoke的

 btn.Click += Displaywebstringlength;


        async void Displaywebstringlength(object sender,EventArgs e)
        {
            label.Text = "Fethcing";
            using (HttpClient client = new HttpClient())                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
            {
                string text =await client.GetStringAsync(@"https://www.baidu.com/");
                label.Text = text.Length.ToString();
            }
        }

并行·

当有大气的非亲非故的事的汇聚要开始展览操作就能够用并行了也正是Parallel,这玩意儿内部也是用task完成的不过完毕写好复杂
没看掌握·····同理可得碉堡了···

也可以用相应的linq达成PLINQ,

建议利用Parallel 那个会依照cpu状态动态调整,而plinq未有那么些思量

比如笔者有一批文件要读取,就能够如此读,或然作者要反省局域网的那多少个IP能ping同,只怕做1些数字的联谊操作

            var nums = Enumerable.Range(1, 20);
            Parallel.ForEach(nums, new Action<int>(n => Console.WriteLine(n)));//Parallel的实现
            nums.AsParallel().ForAll(n => Console.WriteLine(n));//Plinq的实现
//任务并行执行       

Action maction = () => {
Console.WriteLine(“ParelTest”);
};
Parallel.Invoke(maction);

TPL数据流,正是把事件弄的想流1样执行·· 作者实际没搞领悟那玩意儿又啥用
反正很流弊l啦,那些东西供给用nuget下一个微软的库,那个库是至极,也正是不带有在fcl中,Microsoft.Tpl.Dataflow

        static async Task Test()
        {
            //string uri = @"https://www.baidu.com/";
            //string res = await DownloadWrithRitries(uri);
            //Console.WriteLine(res); 
            var multiplyBlock = new TransformBlock<int, int>(item => {
                item = item * 2;
                Console.WriteLine(item);
                return item;
            });
            var substractblock = new TransformBlock<int, int>(item => {
                item = item - 2;
                Console.WriteLine(item);
                return item;
            });
            var opions = new DataflowLinkOptions { PropagateCompletion = true };
            multiplyBlock.LinkTo(substractblock, opions);
            multiplyBlock.AsObserver().OnNext(20);
            multiplyBlock.Complete();
            await substractblock.Completion;
        }

C#,奥迪Q3x这几个也是要经过nuget安装宝马X叁x-Main,这个人是依据IObservable<T>也正是旁观者格局·的玩意··那里不做表达了···首假设自个儿的nuget没下到那玩意·····

此处这是列举了那么些异步的情势·
应该都帮衬打消操作,类似CancellationTokenSource这一个类其他事物·

所以书里边推荐应用Task和async/await,

然后还有涉及同步方式的题材至关首假若阻塞锁,异步锁SemaphoreSlim(其实是限流),阻塞时域信号

要么利用线程安全集合比如ConcurrentBag,ConcurrentDictionary分别对应列表和字典的线程安全集合,类似的还有栈和队列以及set的兑现,那玩意儿内部贯彻类似正是monitor和innerlock协作,说是效能还足以·

·贴个代码··那么些是反编译的ConcurrentBag的拉长操作代码

private void AddInternal(ConcurrentBag<T>.ThreadLocalList list, T item)
{
    bool flag = false;
    try
    {
        Interlocked.Exchange(ref list.m_currentOp, 1);
        if (list.Count < 2 || this.m_needSync)
        {
            list.m_currentOp = 0;
            Monitor.Enter(list, ref flag);
        }
        list.Add(item, flag);
    }
    finally
    {
        list.m_currentOp = 0;
        if (flag)
        {
            Monitor.Exit(list);
        }
    }
}

其它微软还有二个不得变集合库,那玩意儿要求去nuget下载,都以以Immutable开首的··

所谓的不行变意思是每一遍操作都回来三个簇新的集纳,在api达成的时候集合里边完成的存储共享···具体怎么落到实处就不知道了

          var stack = ImmutableStack<int>.Empty;
                stack = stack.Push(13);
                var biggerstack = stack.Push(7);
                foreach (var item in stack)
                    Console.WriteLine(item);
                foreach (var item in biggerstack)
                    Console.WriteLine(item);
//两个栈共享了存储项目13的内存

 

相关文章