我們在處理多線程的任務的時候,有時候要將任務拆分. 比如我的項目中 . 一方面,要採集每秒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上的卡頓,因爲它是異步的,健壯性是相當的好,以此這個爲模板,寫自己的多線程管理類.