[問題] WPF 物件跨執行緒問題

看板C_Sharp作者 (血腹獸)時間13年前 (2010/10/25 08:32), 編輯推噓2(206)
留言8則, 2人參與, 最新討論串1/1
1.原本的做法 // 有一方法可以create出Canvas物件 private Canvas createCanvas(string canvasString) { .... } // 今天有某個迴圈建立了Canvas的集合 IList<Canvas> canvasList = new List<Canvas>(); for(....) { canvasList.Add(createCanvas(..)); } // 再把Canvas集合加到同一個Canvas, 目前為止是ok的 Canvas canvas = new Canvas(); foreach(Canvas c in canvasList) { canvas.Children.Add(c); } 2. 我遇到的問題...多執行緒的做法 // 在上述的第二個迴圈改為 // inner class class ThreadParameter { public string CanvasContentString { get; set; } public IList<Canvas> CanvasList { get; set; } } void ThreadMethod(object obj) { ThreadParameter para = (ThreadParameter)obj; para.CanvasList.Add(createCanvas(para.CanvasContentString)); } IList<Canvas> canvasList = new List<Canvas>(); IList<Thread> threadList = new List<Thread>(); for(...) { ThreadParameter para = new ThreadParameter() { CanvasList = canvasList, CanvasContentString = ...}; Thread t = new Thread(new ParameterizedThreadStart(ThreadMethod)); t.SetApartmentState(ApartmentState.STA); threadList.Add(t); t.Start(para); } foreach(Thread t in threadList) { // 等待執行緒跑完 t.Join(); } // 以上都還沒問題, 以下就是問題, Add到canvas的過程發生Exception Canvas canvas = new Canvas(); foreach(Canvas c in canvasList) { canvas.Children.Add(c); } 例外訊息為 "呼叫執行緒無法存取此物件,因為此物件屬於另一個執行緒" 不知道怎辦 試了Dispatcher的做法 Canvas canvas = new Canvas(); foreach(Canvas c in canvasList) { canvas.Dispatcher.Invoke(DispatcherPriority.Normal, new AddOverLapXaml(canvas.Children.Add), c); } delegate int AddOverLapXaml(UIElement ui); 但仍然有Exception "引動的過程傳回例外" 請問在WPF中 如果是不同Thread所建立的物件想要Add或被Add到UIElementCollection 那個做法是什麼 雖然都用主執行緒可以執行, 但效能真得有差 感恩 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 60.251.1.226 ※ 編輯: kairy 來自: 60.251.1.226 (10/25 09:50)

10/25 23:49, , 1F
canvas.Dispatcher 改成 Application.Current.Dispatcher
10/25 23:49, 1F

10/25 23:51, , 2F
或用 window的 dispatcher 試看看
10/25 23:51, 2F

10/26 07:38, , 3F
To 樓上的板友, 我剛剛試了, 結果還是不行, 錯誤訊息是
10/26 07:38, 3F

10/26 07:39, , 4F
"引動過程的目標傳回例外狀況。", InnerException是
10/26 07:39, 4F

10/26 07:39, , 5F
{"呼叫執行緒無法存取此物件,因為此物件屬於另一個執行緒。
10/26 07:39, 5F

10/26 07:39, , 6F
不過還是非常感謝您~
10/26 07:39, 6F

10/26 16:13, , 7F
那把 canvas 的create 放在UI thread中,如果 canvas 的
10/26 16:13, 7F

10/26 16:14, , 8F
create 中跟ui無關且會佔用cpu太久的部份再另外用thread做
10/26 16:14, 8F
文章代碼(AID): #1CnD0iqc (C_Sharp)