<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      c# 線程使用總結

      C# 里有好幾種線程,每種有不同的實現方式,對應實現不同的功能,做個總結方便以后使用。

       

      1. 委托

      (1) 同步委托開啟線程

      不需要傳參:

      Action action1 = new Action(Count);// count 是一個計數函數
      action1.Invoke();

       

      需要傳參:

      Action<string> action2 = new Action<string>(Count);// Count是一個帶有object參數的計數函數
      action2.Invoke("線程開啟");

      總結:同步委托可以實現傳參與不傳參兩種情況,但使用以后,界面卡頓,大多數情況下不宜使用

       

      (2)異步委托開啟線程

      傳遞參數:

      Action<string> action3 = new Action<string>(Count);// Count是一個帶有object參數的計數函數
      action3.BeginInvoke("線程開啟", null, null);

       傳遞參數并等待線程結束,傳回線程運行之后的返回值:

      private delegate int CallBack(string value);//帶有返回值
      int count = 0;
      private int Back(string str)
      {
         Stopwatch sp = new Stopwatch();
         sp.Start();
         for (int i = 10; i > 0; i--)
         {
              System.TimeSpan startTime = sp.Elapsed;
               while ((sp.Elapsed - startTime).TotalMilliseconds <= 1000)
               {
                     System.Threading.Thread.Sleep(1);
               }
               TextChange(textBox1, str);
               TextChange(textBox2, i.ToString());
               count++;
          }
          return count;
      }
      
      
      CallBack action = new CallBack(Back);
      IAsyncResult cookie = action.BeginInvoke("線程開啟", null, null);
      int return= action.EndInvoke(cookie);

       

      總結:如果只傳遞參數,異步線程不會卡頓,但如果需要等待線程結束 ,用到 action.EndInvoke,界面會卡頓,

      這時外加上一個new Thread或者其他線程,可以解決卡頓問題,這個后面會說到。

       

      (3) 通過thread開啟線程

      傳遞參數:

      Thread thread = new Thread(new ParameterizedThreadStart(Count));// Count是一個帶有object參數的計數函數
      thread.Start("線程開啟");
      //Thread.Sleep(1000);
      //thread.Abort();//線程終止,立馬停下,方法停止
      //Console.WriteLine(thread.ThreadState);

             或者用一個更簡單的方式:

      new Thread((value)=>
      {
           //這里直接寫Count函數的內容
      }).Start("線程開啟");

      不傳遞參數:

      Thread thread = new Thread(new ThreadStart(Count));// Count是不帶參數的計數函數
      thread.Start();
      //Thread.Sleep(1000);
      //thread.Abort();//線程終止,立馬停下,方法停止
      //Console.WriteLine(thread.ThreadState);

            或者(這里演示用new thread解決action.EndInvoke卡頓問題):

      new Thread(()=>
      {
      CallBack action = new CallBack(Back);
      IAsyncResult cookie = action.BeginInvoke("線程開啟", null, null);
      int return= action.EndInvoke(cookie);
      
      int count = 0;
      private int Back(string str)
      {
         Stopwatch sp = new Stopwatch();
         sp.Start();
         for (int i = 10; i > 0; i--)
         {
              System.TimeSpan startTime = sp.Elapsed;
               while ((sp.Elapsed - startTime).TotalMilliseconds <= 1000)
               {
                     System.Threading.Thread.Sleep(1);
               }
               TextChange(textBox1, str);
               TextChange(textBox2, i.ToString());
               count++;
          }
          return count;
      }
      
      }).Start();

       

      (4)  timer開啟線程

      可以傳遞參數并循環執行:

      System.Threading.Timer timer = new System.Threading.Timer(new TimerCallback(Count), "線程開啟", Timeout.Infinite, Timeout.Infinite);// Count是一個帶有object參數的計數函數
      timer.Change(0, 0); //開啟timer
      //Thread.Sleep(100); 
      //timer.Change(-1, -1);//關閉timer,如果count函數沒有執行完,不會停下,直到count函數執行完畢

      總結:如果不需要傳參,把“線程開啟”換成null即可。

      timer.Change(0,0) 中第一個0的位置表示開啟時間(單位ms),0表示立馬執行,-1表示永遠不執行,第二個0的位置表示循環周期(單位ms),0或者-1表示不循環,其他正整數表示循環周期。

       

      (5) Task開啟線程

      不傳遞參數(快速啟動方式):

      Task.Run(() => Count());//Count是一個計時函數

      傳遞參數:

      Task task = new Task(new Action<object>(Count), "線程開啟", cts.Token);//無返回值的傳參
      task.Start();
      
      //或者
      Task.Factory.StartNew(new Action<object>(Count), "線程開啟");

      等待單個線程結束并返回結果:

      int count = 0;
      private int Test2(object obj)
      {
         Stopwatch sp = new Stopwatch();
         sp.Start();
         for (int i = 5; i > 0; i--)
         {
              System.TimeSpan startTime = sp.Elapsed;
              while ((sp.Elapsed - startTime).TotalMilliseconds <= 1000)
               {
                       System.Threading.Thread.Sleep(1);
               }
                 TextChange(textBox2, i.ToString());
                 TextChange(textBox1, obj.ToString());
                 count++;
         }
           return count;
      }
      
      
      
      Func<object, int> func = new Func<object, int>(Test2);            Task<int> task1 = new Task<int>(func, "線程開啟");
      task1.Start();
      
      //if(task1.Result ==5) //直接寫等待并判斷會卡界面
      //{
      //    TextChange(textBox6, task1.Result.ToString());
      //}
      
      
      //開啟另一個task2等待task1結束
      Task task2 = task1.ContinueWith(reValue =>
      {
          if (reValue.Result == 5)
          {
               TextChange(textBox6, reValue.Result.ToString());
           }
           else
           {
                return;
            }
      });

      等待多個線程全部運行結束,并返回結果 :

      int count = 0;
      private int Test2(object obj)
      {
         Stopwatch sp = new Stopwatch();
         sp.Start();
         for (int i = 5; i > 0; i--)
         {
              System.TimeSpan startTime = sp.Elapsed;
              while ((sp.Elapsed - startTime).TotalMilliseconds <= 1000)
               {
                       System.Threading.Thread.Sleep(1);
               }
                 TextChange(textBox2, i.ToString());
                 TextChange(textBox1, obj.ToString());
                 count++;
         }
           return count;
      }
      
      
      List<int> resulesList = new List<int>();
      List<Task<int>> taskList = new List<Task<int>>();
      for (int i = 0; i < 5; i++)
      {
           taskList.Add(Task<int>.Factory.StartNew(new Func<object, int>(test2), i));
      }
      Task.Factory.ContinueWhenAll(taskList.ToArray(), t =>       //通過回調完成主線程任務,ContinueWhenAll創建一組任務,該任務在指定的一組任務完成后開始
      {
           for (int i = 0; i < 5; i++)
           {
               resulesList.Add(taskList[i].Result);
            }
      });

      等待多個線程任一運行結束,并返回結果 :

      Task.Factory.ContinueWhenAny

       總結:Task線程的建立在一定程度上依賴于委托,通常,不需要返回值用Action,需要返回值用Func,也可以自建委托,

      Task可以等待單一線程結束/多個線程結束/任一線程結束,分別對應不同的方法

       

      (6) async / await 異步等待

      沒有返回值的等待:

      private async void Waiting()
      {
         var t = Task.Run(() =>
         {
              Thread.Sleep(5000);
          });
          await t;
      Console.WriteLine("等待結束"); }

       

      等待返回值:

      private async void Waiting()
      {
         var t = Task.Run(() =>
         {
              Thread.Sleep(5000);
              return "線程結束";
          });
          textBox2.Text = await t;        
      }

      總結:這種方式可以等待結果,界面不卡頓,且跨線程修改控件屬性問題也可以避免

       

      posted @ 2022-03-07 18:57  尋找迷途的羔羊  閱讀(650)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲成人av在线资源网| 日本韩国日韩少妇熟女少妇| 精品国产丝袜自在线拍国语| 亚洲男人av香蕉爽爽爽爽| 国产永久免费高清在线观看| 日日碰狠狠躁久久躁96avv| 毛片无码一区二区三区| 欧洲一区二区中文字幕| 狠狠综合久久综合88亚洲爱文| 4hu44四虎www在线影院麻豆| 亚洲国产成人久久77| 日韩免费无码一区二区三区| 成人一区二区不卡国产| 一区二区国产精品精华液| 国产99在线 | 免费| 欧美日韩国产综合草草| 91精品久久久久久无码人妻| 亚洲精品男男一区二区| 亚洲一区二区三区激情视频| 亚洲中文一区二区av| 农村欧美丰满熟妇xxxx| 淅川县| 九九九国产精品成人免费视频| 又爽又黄又无遮掩的免费视频| 武宣县| jk白丝喷浆| 午夜DY888国产精品影院| 女厕偷窥一区二区三区| 成人特黄特色毛片免费看 | 亚洲国产av久久久| 人妻有码av中文字幕久久琪| 国产精品自在自线视频| 亚洲精品国产成人| 中文字幕日韩精品东京热| 最近中文字幕国产精品| 国产亚洲AV电影院之毛片| 公天天吃我奶躁我的在线观看| 99riav国产精品视频| 国产稚嫩高中生呻吟激情在线视频| 亚洲欧美日产综合在线网| 在线综合亚洲欧洲综合网站|