高调

大话讲述的不过是一个不断发生的老套故事。

大话异步与并行(二),大话异步并行

接着上期的文章继续说异步与并行

并行来自于线程的方法实现,异步不一定。这句话,晕倒一大片程序员。

首先,多线程序是实现异步一种方法,两者的共同目的:使主线程保持对用户操作的实时响应,如点击、拖拽、输入字符等。使主程序看起来实时都保持着等待用户响应的状态,而后台却有若干件事情在自己干。按消耗资源所在地可分为两类:硬件异步类和CPU异步类。

硬件异步的特点:将需要在后台执行的操作甩给底层硬件去执行,不占用线程和CPU资源。所以说,并不是所有的异步都占有线程的。

硬件异步类大概有以下这几类。

应用程序范围

支持包含异步方法的 API

Web 访问

HttpClient ,SyndicationClient

处理文件

StorageFile,StreamWriter,StreamReader,XmlReader

使用图像处理

MediaCapture,BitmapEncoder,BitmapDecoder

WCF 编程

同步和异步操作

与套接字处理

Socket

 

威尼斯手机娱乐官网 1

CPU常用的异步方式、方法

1、独立的线程—ThreadStart

     一般情况下,要为不会阻止其他线程的相对较短的任务处理多个线程并且不需要对这些任务执行任何特定调度时,使用 ThreadPool 类是一种最简单的方式。 但是,有多个理由创建您自己的线程:
  • 如果您需要使一个任务具有特定的优先级。

  • 如果您具有可能会长时间运行(并因此阻止其他任务)的任务。

  • 如果您需要将线程放置到单线程单元中(所有 威尼斯手机娱乐官网,ThreadPool 线程均处于多线程单元中)。

  • 如果您需要与该线程关联的稳定标识。
    例如,您应使用一个专用线程来中止该线程,将其挂起或按名称发现它。

  • 如果您需要运行与用户界面交互的后台线程,.NET Framework 2.0
    版提供了 BackgroundWorker 组件,该组件可以使用事件与用户界面线程的跨线程封送进行通信。

2、ThreadPool—ThreadPool.QueueUserWorkItem(M())

3、任务,Task系列–普通任务、关联的任务(Task<T>.ContinueWith(…))、父子任务、任务工厂(TaskTactory<TResult>)

4、Parallel静态类— System.Threading.Tasks.Parallel.For(…)
System.Threading.Tasks.Parallel.ForEach(…) Parallel.Invoke(() =>
Sort());

5、PLINQ

6、定时器  

到此只是简单的基础知识阐述。如果不太清楚,下面的陆续的文章将会一一讲起。


Thread类(线程类)

除了使用委托创建线程之外,还可以使用thread 类创建线程

        static void Main(string[] args)
        {
            Thread t = new Thread(ThreadMain);
            t.Start();
            Console.WriteLine("This ia a mian thread.");
        }

        static void ThreadMain()
        {
            Console.WriteLine("Running in a thread.");
        }

简化以上代码 

 static void Main(string[] args)
        {
            new Thread(() =>
            Console.WriteLine("Running in a thread.")

        ).Start();

            Console.WriteLine("This ia a mian thread.");
        }

再次见证  拉姆达(lambda)表达式与匿名方法 的威力。

在上面简单的Thread类就创建并开始了一个线程。Thread类默认的是 IsBackground =false,也就是说它是前台线程。

说到前台线程与后台线程,上一文章提到,当前台进程停止的时候,后台进程也将停止,当时是放在mian主线程测试的,必须关闭或结束主线程,看的不是太清楚

现在有了Thread类,下面的例子将会开启不依懒主线程的测试。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime now = DateTime.Now;

            Thread t1 = new Thread(() =>
            {
                Console.WriteLine("Running in a thread t1.");
                Func<decimal, int, decimal> f = (money, ms) =>
                {
                    Console.WriteLine("SaveBankAccountPersonA thread started! current run at threadID:" + Thread.CurrentThread.ManagedThreadId);
                    Console.WriteLine("SaveBankAccountPersonA thread IsBackground " + Thread.CurrentThread.IsBackground);
                    Thread.Sleep(ms);
                    Console.WriteLine("SaveBankAccountPersonA thread completed!");
                    return ++money;
                };

                var ar = f.BeginInvoke(1, 200, (r) =>
                {
                    if (r == null)
                    {
                        throw new ArgumentNullException("r");
                    }

                    Thread.Sleep(1000);

                    Console.WriteLine("AsycyCallBackCurrentMoneyPersonA:{0}", f.EndInvoke(r));
                    Console.WriteLine("AsycyCallBackRunTimePersonA:{0}", (DateTime.Now - now).TotalSeconds);
                    Console.WriteLine("AsycyCallBackSaveBankAccountPersonA thread IsBackground " + Thread.CurrentThread.IsBackground);

                }, null);

                while (!ar.IsCompleted)
                {
                    Console.WriteLine("threadT1 wating current run at treadID:" + Thread.CurrentThread.ManagedThreadId);
                    Thread.Sleep(50);
                }
            });

            Thread t2 = new Thread(() =>
            {

                Console.WriteLine("Running in a thread t2.");
                Func<decimal, int, decimal> f = (money, ms) =>
                {
                    Console.WriteLine("SaveBankAccountPersonB thread started! current run at threadID:" + Thread.CurrentThread.ManagedThreadId);
                    Console.WriteLine("SaveBankAccountPersonB thread IsBackground " + Thread.CurrentThread.IsBackground);
                    Thread.Sleep(ms);
                    Console.WriteLine("SaveBankAccountPersonB thread completed!");
                    return ++money;
                };

                var ar = f.BeginInvoke(1, 200, (r) =>
                {
                    if (r == null)
                    {
                        throw new ArgumentNullException("r");
                    }
                    Console.WriteLine("AsycyCallBackCurrentMoneyPersonB:{0}", f.EndInvoke(r));
                    Console.WriteLine("AsycyCallBackRunTimePersonB:{0}", (DateTime.Now - now).TotalSeconds);
                    Console.WriteLine("AsycyCallBackSaveBankAccountPersonB thread IsBackground " + Thread.CurrentThread.IsBackground);

                }, null);

                while (!ar.IsCompleted)
                {
                    Console.WriteLine("threadT2 wating current run at treadID:" + Thread.CurrentThread.ManagedThreadId);
                    Thread.Sleep(50);
                }
            });

            t1.Start();
            t2.Start();
            t1.Abort();

            Console.WriteLine("This ia a mian thread.");
            Console.ReadKey();
        }
    }
}

上面的代码很多,对上一文章的进行扩展。分别启用两个线程t1和t2
,并在每个线程里加入异步委托A和B,从而开始新的后台线程(异步委托默认是后台线程)

威尼斯手机娱乐官网 2

上面这张图,t1还没有来及运行,就已停止,下面这张图,t1运行起来了

威尼斯手机娱乐官网 3

但是A还是没有运行起来,充分说明A一并被t1停止

 

后台线程A和B 同时拥有两个回调函数 ,在A回调函数里 加入了Sleep(1000)
延迟1秒,紧接着外面t1.Abort();结束前台线程t1。从而达到,外面的t1前台线程结束时后台线程A还没有来及结束(实际上已强制性并随t1前台线程结束了!)

这样就验证了,前台线程结束所依懒的后台线程所并随结束的事实!代码就是最好的说明

 

小结:本节在文章一节中着重阐述的前台线程与后台线程作了在Thread类基础上做了实例论证,从而证明,后台线程的生命周期由依懒的前台线程结束而结束。

同时也将异步与多线程进一步举例说明,线程只是异步的一种实现方法!

 

 未完待续…

 

接着上期的文章继续说异步与并行
并行来自于线程的方法实现,异步不一定。这句话,晕倒一大片…

只不过它的讲述太为奇特。鲁迅说,悲剧就是把有价值的东西,撕裂给你看。

而大话不但要撕裂给你看,而且一边撕一边还要逗你笑。脸上在笑,心里在哭;看不懂时笑,看懂了哭;看的时候笑,回味的时候哭。

各种情感齐聚,五味杂陈。这就是周氏的黑色幽默。

故事本身,讲述的是爱情。

相爱的两个人,却不能在一起。于是彼此努力靠近。

而在这过程中,又遇到的新的人,发生了新的故事。

当得到最初想要的时,却发现自己的心意已经和从前完全不一样了。

困惑,不舍,直至混乱。

伤害如箭般无情的射过来,能做的,不过是用自己的身体挡住一部分,再把心爱的人推向安全些的地方。

你当然不会成为英雄,甚至连被你推开的人都注定会抱怨。

你可以爱两个人,却只能选择和一个人在一起。而且往往最终选择的人,并不是你最爱的那个。因为这个世界上充满了责任、世俗和无奈。你可以反抗一次,但是你反抗不了一辈子。

选择,看起来是你在做,其实命运早已注定。一切不过是宿命。

回不去,放不下。

真希望当初的爱能一万年。

发表评论

电子邮件地址不会被公开。 必填项已用*标注