C# for Beginner Part 86 to 97

Part 86   Multithreading in C#

What is a Process:

Process is what the operatin system uses to facilitate(帮助) the execution of a program by providing the resources required.Each process has unique process Id associated with(关联) it. You can view the process within which a program is being executed using windows task manager.

What is Thread:

Thread is a light weight(轻量级) process.A process has at least one thread which is commonly called(通常被称为) as main thread which actually executes the application code. A single process can hava multiple threads.

Please Note: All the threading related classes are present in(存在于) System.Threading namespace.

Part 87   Advantages and disadvantages of multithreading

Advantages of multithreading:

1, To maintain a responsive user interface(快速响应用户界面)

2, To make effcient use of processor time while waiting for I/O operations to complete.(适当的利用处理器,在等待I / O操作完成的这段时间。)

3, To split large, CPU-bound tasks to be processed simultaneously on a machine that has multiple processors/cores(分割大cpu密集型任务处理的机器上同时有多个处理器/核心)

Disadvantages of multithreading:

1, On a single processor/core machine threading can affect performance negatively as there is overhead involved with context-switching.(在单个处理器/核心的机器,线程会对上下文切换开销的性能有负面影响)

2, Have to write more lines of code to accomplish the same task.(需要编写更多的代码来完成相同的任务)

3,Multithreaded applications are difficult to write, understand, debug and maintain.(多线程应用程序很难写,理解、调试和维护。)

Please Note: Only use multithreading when the advantages of doing so outweigh the disavantages.

Part 88   ThreadStart delegate

To create a Thread, create an instance of Thread class and to it‘s constructor pass the name of the function that we want the thread to execute.

class Program
    {
        static void Main(string[] args)
        {
            Thread t = new Thread(Number.Print);
            t.Start();
        }
    }

    public class Number
    {
        public static void Print()
        {
            for(int i=0;i<10;i++)
            {
                Console.WriteLine(i);
            }
        }
    }

Thread

Thread t = new Thread(Number.Print);
 t.Start();

We can rewrite the above line using ThreadStart delegate as shown below

Thead t1 = new Thread(new ThreadStart(Number.Print));

t1.Start();

Why a delegate need to be passed as a parameter to the Thread class constructor?

The purpose of creating a Thread is to execute a function. A delegate is a type safe function pointer, meaning it points to a function that the thread has to execute. In short, all threads require an entry point to start execution. Any thread you create will need an explicitly defined entry point i.e(那就是说) a pointer to the function where they should begin execution. So threads always require a delegate.

In the code below, we are not explicitly creating the ThreadStart delegage, then how is it working here?

Thread t1 = new Thread(Number.Print);

t1.Start();

It‘s working in spite of(尽管) not creating the ThreadStart delegage explictly because the framework is doing it automatically for us.

Other ways, We can also rewrite the same line using delegate() keyword

Thread t = new Thread(delegate(){Number.Print();});

The same line rewritten using lambda expression

Thread t = new Thread(()=>Number.Print());

Part 89   ParameterizedThreadStart delegate

Use ParameterizedThreadStart delegate to pass data to the thread function

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("input a target number:");
            object target = Console.ReadLine();
            ParameterizedThreadStart pt = new ParameterizedThreadStart(Number.Print);//really need to write that?No,you can just pass the function into Thread class.
            Thread t = new Thread(pt);//new Thread(Number.Print);
            t.Start(target);
            Console.ReadLine();
        }
    }

    public class Number
    {
        public static void Print(object target)
        {
            int number = 0;
            if (int.TryParse(target.ToString(), out number))
            {
                for (int i = 0; i < number; i++)
                {
                    Console.WriteLine(i);
                }
            }
        }
    }

How we are not explictly creating an instance of ParameterizedThreadStart delegate.Then how is it working?

It‘s working because, the compiler implicitly converts new Thread(Number.Print); to new Thread(new ParameterizedThreadStart(Number.Print));

When to use ParameterizedThreadStart over ThreadStart delegate?

Use ParameterizedThreadStart delegate if you have some data to pass to the Thread function, otherwise just use ThreadStart delegate.

Please note: Using parameterizedThreadStart delegate and Thread.Start(Object) method to pass data to the Thread function is not type safe as they operate on object datatype and any type of data can be passed.

If you try to change the data type of the target parameter of Print() function from object to int, a compiler error will be raised as the signature of Print() function does not match with the signature of ParameterizedThreadStart delegate.

Part 90   Passing data to the Thread function in a type safe manner(in a manner..在某种程度上)

To pass data to the Thread function in a type safe manner, encapsulate the thread function and the data it needs in a helper class and use the ThreadStart delegate to execute the thread function.

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("input a target number:");
            int target = Convert.ToInt32(Console.ReadLine());
            Number number = new Number(target);
            Thread t = new Thread(number.Print);
            t.Start();
            Console.ReadLine();
        }
    }

    public class Number
    {
        int _target;
        public Number(int target)
        {
            this._target = target;
        }
        public void Print()
        {
            int number = 0;
            for (int i = 0; i < _target; i++)
            {
                Console.WriteLine(i);
            }
        }
    }

Part 91   Retrieving data from Thread function using callback method

Callback method to get data from thread

Main thread retrieves(检索) the target number from the user.

Main thread creates a child thread and pass the target number to the child thread.

The child thread computes the sum of numbers and then returns the sum to the Main thread using callback function.

The callback method prints the sum of numbers.

Step 1: Create a callback delegate. The actual callback method signature should match with the signature of this delegate.

public delegate void SumOfNumberCallback(int sumOfNumber);

Step 2:Create a helper class to compute the sum of numbers and to call the callback method.

 public class Number
    {
        int _target;
        SumOfNumberCallback _callBackMethod;
        public Number(int target, SumOfNumberCallback callBackMethod)
        {
            this._target = target;
            this._callBackMethod = callBackMethod;
        }
        public void PrintSumOfNumber()
        {
            int sum = 0;
            for (int i = 1; i <= _target; i++)
            {
                sum = sum + i;
            }
            if(_callBackMethod!=null)
            {
                _callBackMethod(sum);
            }
        }
    }

Step 3:This class consumes the Number class create in Step 2

class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("input a target number:");
            int target = Convert.ToInt32(Console.ReadLine());
            SumOfNumberCallback callBack = new SumOfNumberCallback(PrintSum);
            Number number = new Number(target,callBack);
            Thread t = new Thread(number.PrintSumOfNumber);
            t.Start();
            Console.ReadLine();
        }

        public static void PrintSum(int sum)
        {
            Console.WriteLine("sum of number =" + sum);
        }
    }

 Part 92   Significance of Thread Join and Thread IsAlive functions

Thread.Join & Thread.IsAlive functions

Join blocks the current thread and makes it wait until the thread on which Join method is invoked completes.Join method also has a overload where we can specify the timeout. If we don‘t specify the timeout the calling thread waits indefinitely(无限期地), until the thread on which Join() is invoked completes. This overloaded Join(int millisecondesTimeout) method returns boolean. True if the thread has terminated(终止) otherwise false.

Join is particularly(特别地) useful when we need to wait and collect result from a thread execution or if we need to do some clean-up after the thread has completed.

IsAlive returns boolean. True if the thread is still executing otherwise false.

public static void Main(string[] args)
        {
            Console.WriteLine("main start");
            Thread t1 = new Thread(ThreadFunction1);
            t1.Start();
            Thread t2 = new Thread(ThreadFunction2);
            t2.Start();
            if(t1.Join(1000))
            {
                Console.WriteLine("threadfunction1 end");
            }
            else
            {
                Console.WriteLine("threadfunction1 still working");
            }
            if(t1.IsAlive)
            {
                for (int i = 1; i < 10; i++)
                {
                    Console.WriteLine("threadfunction1 still working...");
                    Thread.Sleep(500);
                }
            }
            Console.WriteLine("main end");
        }

        public static void ThreadFunction1()
        {
            Console.WriteLine("threadfunction1 start");
            Thread.Sleep(5000);
            Console.WriteLine("threadfunction1 end");
        }

        public static void ThreadFunction2()
        {
            Console.WriteLine("threadfunction2 start");
        }

Part 93   Protecting shared resources from concurrent access in multithreading

Part 94   Difference between Monitor and lock in C#

Part 95   Deadlock in a multithreaded program

 class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("main start");
            Account a1 = new Account(001,10000);
            Account a2 = new Account(002,20000);
            AccountManager m1 = new AccountManager(a1,a2,5000);
            Thread t1 = new Thread(m1.Transfer);
            t1.Name = "t1";
            AccountManager m2 = new AccountManager(a2, a1, 3000);
            Thread t2 = new Thread(m2.Transfer);
            t2.Name = "t2";
            t1.Start();
            t2.Start();
            t1.Join();
            t2.Join();
            Console.WriteLine("main end");
        }
    }

    class Account
    {
        public int ID { get; set; }
        public double Balance { get; set; }
        public Account(int id, double balance)
        {
            this.ID = id;
            this.Balance = balance;
        }
        public void WithDraw(double amount)
        {
            Balance -= amount;
        }
        public void Deposit(double amount)
        {
            Balance += amount;
        }
    }

    class AccountManager
    {
        public Account FromAccount { get; set; }
        public Account ToAccount { get; set; }
        public double AmountToTransfer { get; set; }
        public AccountManager(Account from,Account to,double amountToTransfer)
        {
            this.FromAccount = from;
            this.ToAccount = to;
            this.AmountToTransfer = amountToTransfer;
        }
        public void Transfer()
        {
            Console.WriteLine(Thread.CurrentThread.Name+"try to acquire lock on"+FromAccount.ID.ToString());
            lock (FromAccount)
            {
                Console.WriteLine(Thread.CurrentThread.Name+" acquired lock on "+FromAccount.ID.ToString());
                Console.WriteLine(Thread.CurrentThread.Name+" suspended for 1 second");
                Thread.Sleep(1000);
                Console.WriteLine(Thread.CurrentThread.Name+"back in action and try to acquire lock on" +ToAccount.ID.ToString());
                lock (ToAccount)
                {
                    Console.WriteLine("this code will not execute");
                    FromAccount.WithDraw(AmountToTransfer);
                    ToAccount.Deposit(AmountToTransfer);
                }
            }
        }

    }

Part 96   How to resolve a deadlock in a multithreaded program

 static void Main(string[] args)
        {
            Console.WriteLine("main start");
            Account a1 = new Account(101,10000);
            Account a2 = new Account(102,20000);
            AccountManager m1 = new AccountManager(a1,a2,5000);
            Thread t1 = new Thread(m1.Transfer);
            t1.Name = "t1";
            AccountManager m2 = new AccountManager(a2, a1, 3000);
            Thread t2 = new Thread(m2.Transfer);
            t2.Name = "t2";
            t1.Start();
            t2.Start();
            t1.Join();
            t2.Join();
            Console.WriteLine("main end");
        }
    }

    class Account
    {
        public int ID { get; set; }
        public double Balance { get; set; }
        public Account(int id, double balance)
        {
            this.ID = id;
            this.Balance = balance;
        }
        public void WithDraw(double amount)
        {
            Balance -= amount;
        }
        public void Deposit(double amount)
        {
            Balance += amount;
        }
    }

    class AccountManager
    {
        public Account FromAccount { get; set; }
        public Account ToAccount { get; set; }
        public double AmountToTransfer { get; set; }
        public AccountManager(Account from,Account to,double amountToTransfer)
        {
            this.FromAccount = from;
            this.ToAccount = to;
            this.AmountToTransfer = amountToTransfer;
        }
        public void Transfer()
        {
            object _lock1, _lock2;
            if(FromAccount.ID<ToAccount.ID)
            {
                _lock1 = FromAccount;
                _lock2 = ToAccount;
            }
            else
            {
                _lock1 = ToAccount;
                _lock2 = FromAccount;
            }
            Console.WriteLine(Thread.CurrentThread.Name+"try to acquire lock on "+((Account)_lock1).ID.ToString());
            lock (_lock1)
            {
                Console.WriteLine(Thread.CurrentThread.Name + " acquired lock on " + ((Account)_lock1).ID.ToString());
                Console.WriteLine(Thread.CurrentThread.Name+" suspended for 1 second");
                Thread.Sleep(1000);
                Console.WriteLine(Thread.CurrentThread.Name + "back in action and try to acquire lock on " + ((Account)_lock2).ID.ToString());
                lock (_lock2)
                {
                    Console.WriteLine(Thread.CurrentThread.Name + " acquired lock on " + ((Account)_lock2).ID.ToString());
                    FromAccount.WithDraw(AmountToTransfer);
                    ToAccount.Deposit(AmountToTransfer);
                    Console.WriteLine(Thread.CurrentThread.Name+" Transferd "+AmountToTransfer.ToString()+" from "+FromAccount.ID.ToString()+" to "+ToAccount.ID.ToString());
                }
            }
        }

Part 97   Performance of a multithreaded program

class Program
    {
        static void Main(string[] args)
        {
            Stopwatch s = new Stopwatch();
            s.Start();
            EvenNumbersSum();
            OddNumbersSum();
            s.Stop();
            Console.WriteLine("before using multiple threads"+s.ElapsedMilliseconds);
            s = new Stopwatch();
            s.Start();
            Thread t1 = new Thread(EvenNumbersSum);
            Thread t2 = new Thread(OddNumbersSum);
            t1.Start();
            t2.Start();
            t1.Join();
            t2.Join();
            s.Stop();
            Console.WriteLine("after using multiple threads"+s.ElapsedMilliseconds);

        }

        public static void EvenNumbersSum()
        {
            double sum=0;
            for(int i=0;i<=50000000;i++)
            {
                if(i%2==0)
                {
                    sum += i;
                }
            }
            Console.WriteLine("sum= "+sum);
        }

        public static void OddNumbersSum()
        {
            double sum = 0;
            for (int i = 0; i <= 50000000; i++)
            {
                if (i % 2 == 1)
                {
                    sum += i;
                }
            }
            Console.WriteLine("sum= " + sum);
        }
    }

时间: 2024-10-21 10:01:32

C# for Beginner Part 86 to 97的相关文章

顶上来咖啡馆的身高多少科技开始打开时间大概会感受到

http://passport.baidu.com/?business&un=%E9%BE%99%E4%BA%95SM%E5%8F%AB%E5%B0%8F%E5%A7%90 http://passport.baidu.com/?business&un=%E8%B0%83%E5%85%B5%E5%B1%B1SM%E5%8F%AB%E5%B0%8F%E5%A7%90 http://passport.baidu.com/?business&un=%E5%9E%A6%E5%88%A9SM%

分享我对 ASP.NET vNext 的一些感受,也许多年回过头看 So Easy!

今天有幸被召回母校给即将毕业的学弟学妹们讲我这两年的工作史,看了下母校没啥特别的变化,就是寝室都安了空调,学妹们都非常漂亮而已..好了不扯蛋了,说下今天的主题吧.这些天我在深度定制语法高亮功能的同时发现了博客园提供的一些有意思的函数,甚至有几个博客园都没用到,我也不知道怎么才能触发那些功能..打开这个js就可以看到很多好用的东西了,虽然写的不怎么样,但是至少有这些功能. ps: 推荐安装一个代码格式化的插件,否则一坨看着蛋疼.比如第一个就是 log,方便调试. www.pinterest.com

ASP.NET MVC 控制器激活(二)

今天有幸被召回母校给即将毕业的学弟学妹们讲我这两年的工作史,看了下母校没啥特别的变化,就是寝室都安了空调,学妹们都非常漂亮而已..好了不扯蛋了,说下今天的主题吧.这些天我在深度定制语法高亮功能的同时发现了博客园提供的一些有意思的函数,甚至有几个博客园都没用到,我也不知道怎么才能触发那些功能..打开这个js就可以看到很多好用的东西了,虽然写的不怎么样,但是至少有这些功能. ps: 推荐安装一个代码格式化的插件,否则一坨看着蛋疼.比如第一个就是 log,方便调试. www.pinterest.com

高手的数据库

http://www.pinterest.com/i4g48swe/%E4%B8%B4%E5%AE%89%E6%89%BE%E5%B0%8F%E5%A7%90%E4%B8%8A%E9%97%A8%E6%9C%8D%E5%8A%A1%E7%94%B5%E8%AF%9D/ http://www.pinterest.com/7p1djvj9/%E6%A1%90%E5%BA%90%E6%89%BE%E5%B0%8F%E5%A7%90%E4%B8%8A%E9%97%A8%E6%9C%8D%E5%8A%A1

移动端HTML5&lt;video&gt;视频播放优化实践

转帖: http://www.xuanfengge.com/html5-video-play.html 如果侵权请告知删除 遇到的挑战 移动端HTML5使用原生<video>标签播放视频,要做到两个基本原则,速度快和体验佳,先来分析一下这两个问题. 下载速度 以一个8s短视频为例,wifi环境下提供的高清视频达到1000kbps,文件大小大约1MB:非wifi环境下提供的低码率视频是500kbps左右,文件大小大约500KB:参考QzoneTouch多普勒测速,2g网络的平均速度是14KB/s

Heartbeat+Drbd+NFS高可用实现

继续之前的操作,来完成heartbeat+drbd+nfs高可用的实现. heartbeat+drbd还是使用原来的环境即可,然而需要添加一台nfs客户端,客户端的信息如下: 主机名 IP地址 角色 server136.contoso.com 192.168.49.136 nfs客户端 一.环境准备 1)注意:因为我的客户端是192.168.49.0/24端,所以这里需要把VIP改为这个网段,所以先修改两个节点的haresources文件,将VIP修改为192.168.49.100.可以根据实际

樟坡我谄套e0m2rfs2

--伊莱克斯对于金融机构纷纷施以的援手,有媒体援引知情人士的表态称,霍雨浩在短暂的震惊之后也冷静了下来,有些无奈的道:"行吧.反正我这条命也交给你了,就算你把我卖了,我也只能给你数钱.走吧,早死早超生,咱们怎么走?"在这所有的核心弟子之中,论战斗力.攻击力,最为强悍的既不是贝贝也不是徐三石,而是同样四环闪耀.并且刚刚进入四级魂导师门槛的和菜头.四强战要开始了,精彩的大**也将随之展开.大家可以猜猜,霍雨浩和王冬的武魂融合技,名字都叫做什么."肯定".去年我国经济增速

脱挚诼鞠旧w4hw605id97f8g6672ht

"哈哈哈哈--"众位宿老顿时集体笑场了.四位院长也是忍俊不禁,仙琳儿甚至用手捂住了自己的脸.刺耳的摩擦中,尽管那已经化为坚硬金属的双翼挡住了戴钥衡的去路,但是,戴钥衡锋锐的金色虎爪却在摩擦中硬生生的抓入了对手的双翼之中."就两个?"周漪眉毛挑了挑,"真是一群废物.难道你们不知道什么叫不敢惹事是庸才吗?除了他们俩以外,其他人全都给我出去,绕着史莱克广场跑一百圈.谁跑不完,直接开除."天梦冰蚕道:"倒不是只有我那里才有精神属性的魂兽.星斗大

驴站苤醚县s2ye68fz7qm9s

剧烈的轰鸣中,竟然没有一处攻击能够真正落在他身上而徐三石就在这骤然的加速之中,穿越枪林弹雨,来到了司徒宇近前继续求收藏.求会员点击.求推荐票!!!新书需要大家的鼎力支持.冰帝之螯,作为冰碧帝皇蝎赋予霍雨浩的强大魂技,虽然霍雨浩现在还不能将它的威力完全发挥出来.但它的特性却还是都在的.徐三石一咬牙,道:"好,我跟你赌.你这贱人,实力未必比我强,但却奸猾的很,估计又上你当了.上当我也认了.大不了下次回家再跟我老爹磨一磨."告别了老师.和菜头,霍雨浩直接回到宿舍,一进门,就看到王冬在那里一脸