1. 程式人生 > 其它 >Parallel.Invoke 並行的使用

Parallel.Invoke 並行的使用

Parallel類 在System.Threading.Tasks 名稱空間下

下面有幾個方法,這裡講一下Invoke的用法

下面我們定義幾個方法方便測試

先自定義Response 防止並行的時候佔用導致結果變化

HttpResponse MyResponse = System.Web.HttpContext.Current.Response;

        public void ResponseWrite1()
        {
            string str = "1:";
            for (int i = 0; i < 10; i++)
            {
                System.Threading.Thread.Sleep(15);
                str += i;
            }
            lock (MyResponse)
            {
                MyResponse.Write(str + "<br /><br />");
            }
        }

        public void ResponseWrite2()
        {
            string str = "2:";
            for (int i = 0; i < 10; i++)
            {
                System.Threading.Thread.Sleep(15);
                str += i;
            }
            lock (MyResponse)
            {
                MyResponse.Write(str + "<br /><br />");
            }
        }

        public void ResponseWrite3()
        {
            string str = "3:";
            for (int i = 0; i < 10; i++)
            {
                System.Threading.Thread.Sleep(15);
                str += i;
            }
            lock (MyResponse)
            {
                MyResponse.Write(str + "<br /><br />");
            }
        }

接下來開始使用並行

可以通過以下方式並行執行不帶引數的方法(☆☆Invoke只能傳入方法名)

            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();
            ResponseWrite1();
            ResponseWrite2();
            ResponseWrite3();

            watch.Stop();
            MyResponse.Write($"<br />普通序列耗時:{ watch.Elapsed.Milliseconds }毫秒<br /><br />");



            System.Diagnostics.Stopwatch watch2 = new System.Diagnostics.Stopwatch();
            watch2.Start();

            Parallel.Invoke(ResponseWrite1, ResponseWrite2,ResponseWrite3);
            
            watch2.Stop();
            MyResponse.Write($"<br />使用並行耗時:{ watch2.Elapsed.Milliseconds }毫秒<br /><br />");

執行結果如下:(☆☆☆特別需要注意的是通過Invoke執行的順序是不固定的)

我們可以看到此時執行同樣的程式碼 並行顯然更加節省時間

那我們想要執行帶引數的方法有沒有辦法呢?

答案當然是可以的

我們可以通過使用Lambda 的方式來執行(當然也可以使用委託的方式)

先我們測試的方法加個引數

        public void ResponseWrite1(string param1 = "test")
        {
            string str = param1 + "1:";
            for (int i = 0; i < 10; i++)
            {
                System.Threading.Thread.Sleep(15);
                str += i;
            }
            lock (MyResponse)
            {
                MyResponse.Write(str + "<br /><br />");
            }
        }

通過lambda執行帶參的方法

       System.Diagnostics.Stopwatch watch =newSystem.Diagnostics.Stopwatch();           
       watch.Start(); ResponseWrite1(); ResponseWrite2(); ResponseWrite3(); watch.Stop(); MyResponse.Write($"<br />普通序列耗時:{ watch.Elapsed.Milliseconds }毫秒<br /><br />"); System.Diagnostics.Stopwatch watch2 = new System.Diagnostics.Stopwatch(); watch2.Start(); Parallel.Invoke( () => ResponseWrite1("哈哈哈"), () => ResponseWrite2(), delegate() {
            ResponseWrite3();
          }
            );

            watch2.Stop();
            MyResponse.Write($"<br />使用並行耗時:{ watch2.Elapsed.Milliseconds }毫秒<br /><br />");

Parallel.Invoke方法只有在所有方法全部執行完畢後才會返回,即使在方法執行過程中出現異常Invoke也會完成

所以我們在使用Parallel.Invoke的時候也要考慮裡面的方法執行時間是否差不多,如果有一個方法執行時間比較長,也會拖累其他方法(因為Invoke會等所有方法執行完畢後才會返回)

以上就是Parallel.Invoke的用法,如果有不對或者可以改進的地方,歡迎留言