這裏有必要記錄一下 .net wpf中多線程中的使用情況.以做記錄

      我們在處理多線程的任務的時候,有時候要將任務拆分. 比如我的項目中 . 一方面,要採集每秒300多張圖片來供點雲生成;同時,要將處理之後的圖片分組,進行三維點雲的生成;以及對點雲的的拼接以及顯示;

     如何做來滿足這些高cpu,gpu的處理呢?多線程,但是,大家一定要注意,在這三個線程中的數據處理,一定要做隊列上的緩衝,也就是,自己要設計三個緩衝類,而且是加鎖和線程安全的,這樣才能同時運作.

        而在wpf中,我們很容易使用委託,task等已經分裝好的類。下面記錄一個這個自己設計的線程類,同時包括開啓,停止線程的功能.

//這裏就以我  點雲拼接並顯示異步線程. 案例,來講解.

  //這個類是我設計的保存的3維數據,大家可以依據自己的情況,來寫自己的結構
  [StructLayout(LayoutKind.Sequential)]
    public struct AscDataD3Struct
    {
        public float u;
        public float v;
        public float x;
        public float y;
        public float z;

        public byte R;
        public byte G;
        public byte B;

        public float p3x;
        public float p3y;
        public float p3z;
        public int ID;

    };

class joinPoint3D
{

        public bool IsStop_MatchingD3CloundThread = true;
        public CancellationTokenSource CancellAsync_MatchingD3CloundSource = 
     CancellationTokenSource();
        public int MatchingD3Clound_Delay = 10; //設置線程執行時間..
        public bool IsClearGetListPoind3s = false;//是否清空當前的點雲內存結構.
        public List<AscDataD3Struct> GetListAscPointAllD3s = new List<AscDataD3Struct>();//這裏儲存着最後獲取到的點雲數量...

         public void AscP3dCloundsSplicingMethod()
        {
            int temp = -1;
            try
            {

                //這裏不停的獲取其拼接狀態 這是我自己寫的DLL中的api
                temp = yws_InterFaceSDK.DLL_outManegeDataToOsg();

                if (temp != 0)
                {
                    Debug.WriteLine("拼接數據失敗 :" + temp.ToString());
                }
                else
                {
                    Debug.WriteLine("拼接數據成功.: " + temp.ToString());

                }


            }
            catch (Exception ex)
            {
                Debug.WriteLine("點雲生成異常: " + ex.Message);
                return;
            }
            finally
            {
                
            }
        }

        //注意這裏的 async 以及 await 同時出現。
       public async Task AscP3dCloundsSplicingThread(CancellationToken ct)
        {
            while (IsStop_MatchingD3CloundThread)
            {

                //判斷上面CancellationTokenSource  這個對象是否終止的條件.
                if (CancellAsync_MatchingD3CloundSource.IsCancellationRequested)
                {
                    break;
                }


                //這裏就是採用了應答的方式,在其他線程處理好了之後,發一個信號過來,讓這個線程處理數據,大家不懂的可以看看多線程 信號這方面的知識
                if (IsICPRegister.WaitOne() == true)
                {
                    
                    Task.Factory.StartNew(AscP3dCloundsSplicingMethod).Wait();
                }

                await Task.Delay(MatchingD3Clound_Delay);
                ct.ThrowIfCancellationRequested();
            }
        }

         public async void AscP3dCloundsSplicingTask()
        {
            IsStop_MatchingD3CloundThread = true;

            var aCanccel =             
            AscP3dCloundsSplicingThread(CancellAsync_MatchingD3CloundSource.Token);
            try
            {
                Debug.WriteLine("點雲拼接任務開啓....");
                await aCanccel;
            }
            catch
            {
                if (aCanccel.IsCanceled)
                {
                    Console.WriteLine("點雲拼接任務結束....");
                }
            }
        }

          public void Async_P3dCloundsSplicingStart()
        {

//注意這裏,每次開始線程的時候,必須要重新new這個對象,否則上面的線程是開啓不了的
            CancellAsync_MatchingD3CloundSource = new CancellationTokenSource();
            Task.Factory.StartNew(AscP3dCloundsSplicingTask, CancellAsync_MatchingD3CloundSource.Token, TaskCreationOptions.None, TaskScheduler.Default);

        }
        public void Async_P3dCloundsSplicingStop()
        {
            try
            {
                CancellAsync_MatchingD3CloundSource.Cancel();
                IsStop_MatchingD3CloundThread = false;

            }
            catch (Exception ex)
            {
                Console.WriteLine("點雲拼接停止異常: " + ex.Message);
            }
        }

}



經過以上這麼設計,我們的這個線程就可以隨時停止,開啓,而且不會造成奔潰以及ui上的卡頓,因爲它是異步的,健壯性是相當的好,以此這個爲模板,寫自己的多線程管理類.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章