C_Sharp 板


LINE

最近負責開發一個dll,裡面包含了一個UserControl(以下簡稱 UC) 這個UC含有許多功能,所以,UC有錯誤時,希望能夠透過本身的介面顯示出來。 因此這個UC會有一個Rirchtextbox 來顯示UC的log並寫成file。 另一位朋友,則是負責開發Form,並把我的UC 加入到他的Form。 但問題發生了,當他將我的UC初始化完成後,Add UC到他的Form。 系統卻拋出跨執行緒處理異常的錯誤 ==> 如右圖 http://i.imgur.com/BlIKUOm.jpg 我和朋友嘗試的許多方式,還是會出現錯誤。而且,如果執行 Richtextbox.Text = "aaa"; ==> 不會出現錯誤 Richtextbox.AppendText("aaa"); ==> 拋出跨執行緒錯誤 嘗試使用RichtextBox和TextBox 都是相同錯誤。... 附上簡單寫的Code (Mega空間) => https://4fun.tw/IDMo 原始路徑: https://mega.nz/#!6AoxHTAJ!DWJmWJhT9t7NhesNizTZVPZawbrByImnVM2h_eZn87k 請教一下各位前輩,到底是什麼原因造成的呢? 有什麼解決方式呢?? 謝謝 --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.27.132.126
※ 文章網址: https://webptt.com/m.aspx?n=bbs/C_Sharp/M.1459174541.A.A5C.html
1F:推 yeo1987: 你程式中有兩個Thread,一個是程式啟動時UI的主Thread, 03/28 22:56
2F:→ yeo1987: 另一是每次Click時產生的新的Thread,你把UserControl建 03/28 22:56
3F:→ yeo1987: 立在新的Thread中,卻用主Thread去Invoke,就跨執行續了 03/28 22:57
4F:→ don750421: 感謝yeo解惑,這個問題我也有詢問過我朋友.. 03/28 23:02
5F:→ don750421: 他的Form會引用不同模組,每個模組都是建立不同的 03/28 23:03
6F:→ don750421: Thread去處理,所以,建立UC和呼叫UC的不一定是同一個 03/28 23:03
7F:→ don750421: Thread,如果是這樣的話,有甚麼辦法解決呢? 03/28 23:04
※ 編輯: don750421 (114.27.132.126), 03/28/2016 23:05:00
8F:推 yeo1987: Control.Invoke是以該物件所屬的執行續執行委派,因此, 03/28 23:18
9F:→ yeo1987: 只要UserControl是在主執行續下建立,執行流程中跨執行續 03/28 23:20
10F:→ yeo1987: 時,需要涉及UI,使用UserControl.Invoke就可以了。 03/28 23:20
11F:→ yeo1987: 其實因為你負責開發UserControl,你只要保證操作UI時是在 03/28 23:24
12F:→ yeo1987: UserControl所屬的執行續下執行。 03/28 23:25
13F:→ yeo1987: 發現緒一直打錯... - - 03/28 23:29
14F:→ don750421: 請教一下,您指的"只要UserControl是在主執行續下建立" 03/28 23:39
15F:→ don750421: 是指Form的主執行緒?還是UC的主執行緒? 03/28 23:40
16F:→ don750421: 如果是Form的主緒,有和開發Form的人員討論過.. 03/28 23:41
17F:→ don750421: 因為Form的主緒還會去呼叫其他的Thread處理事情... 03/28 23:42
18F:→ don750421: 如果拿Form的主緒呼叫我的UC,則畫面會有停頓的情況... 03/28 23:42
19F:→ yeo1987: 以上是指同一個,Multi UI Thread我想不是你要問的問題… 03/28 23:43
20F:→ yeo1987: 我指的是"建立"與"操作UI"時,使用主執行續呼叫。 03/28 23:44
21F:→ yeo1987: 如果你開一個新的執行續,裡面的工作卻是不停更新UI,自 03/28 23:45
22F:→ yeo1987: 然會卡。 03/28 23:46
※ 編輯: don750421 (114.27.132.126), 03/28/2016 23:50:51
23F:→ don750421: 因為之前顯示Log的方式,是使用DataGridview,每一筆 03/28 23:54
24F:→ don750421: Log就只需要datagridview.rows.add("xxx")加入 03/28 23:55
25F:→ don750421: 想說換成TextBox簡單一些,但是開發Form的就說,之前 03/28 23:55
26F:→ don750421: 呼叫方式也沒變,為什麼換成textbox就不行... 03/28 23:56
27F:→ don750421: 不然,我也想說,明明我自己寫Log也都正常啊 = =||| 03/28 23:56
28F:→ don750421: 和開發Form的討論過,主Thread不能拿來new 我的UC 03/28 23:57
29F:→ don750421: 所以,在Sample才會new Thread 來模擬現有的情況... 03/28 23:58
30F:→ don750421: 而且,UC並非只有顯示Log而已,還有其他的功能.. 03/29 00:04
31F:→ don750421: 我這邊只有濃縮有問題的部分寫成Sample.. 03/29 00:04
32F:→ don750421: 所以,除了透過主Thread建立我的UC外,還有其他方式嗎? 03/29 00:05
33F:→ yeo1987: 這樣的要求... 那你在Contructor內不要呼叫Log操作UI, 03/29 00:21
34F:→ yeo1987: 並且在公開呼叫的方法內,操作UI的部分都要檢查是否需要 03/29 00:21
35F:→ yeo1987: Invoke 03/29 00:21
36F:→ yeo1987: Constructor -.-,BTW,這樣的做法真的不推薦... 03/29 00:26
37F:→ Litfal: 我說,你們是在把事情搞複雜...... 03/29 03:19
38F:推 yeo1987: L大的解法會是?想學習 03/29 08:06
39F:→ Litfal: 我是說原PO和他朋友,這種比較複雜的需求應該把系統邊界定 03/29 16:16
40F:→ Litfal: 好,中間的操作介面也定義出來。 03/29 16:17
41F:→ yeo1987: 認同L大,說真的原PO若堅持要在不同執行緒下操作UI,WIN 03/29 18:59
42F:→ yeo1987: Form中是有Control.CheckForIllegalCrossThreadCalls可以 03/29 18:59
43F:→ yeo1987: 攔截錯誤,但是這樣寫出來的程式,沒問題就沒問題,出問 03/29 19:00
44F:→ yeo1987: 題時很難找到問題點。 03/29 19:01
45F:→ don750421: 感謝兩位前輩回覆,今天詢問朋友的結果... 03/29 23:41
46F:→ don750421: 朋友的Form介面跟我提供的Sample雷同,會有許多TabPage 03/29 23:42
47F:→ don750421: 而他的TabPage是以他的MainThread來初始化... 03/29 23:42
48F:→ don750421: 但是,因為我的是引用的部分,所以會是另外一個Thread 03/29 23:43
49F:→ don750421: 如果都使用MainThread,變得需要先長我的TabPage,在長 03/29 23:43
50F:→ don750421: 他的,這樣在畫面上會造成一些些的延遲,反之,如果先 03/29 23:44
51F:→ don750421: 建他的TabPage,最後跑到我的UC時,也會稍微有一些些 03/29 23:44
52F:→ don750421: 延遲的感覺... 03/29 23:45
53F:→ don750421: 而且,因為我的dll是使用動態呼叫,也等於說,不一定在 03/29 23:46
54F:→ don750421: 每一個場合都需要引用我的UC,所以才會另起一個Thread 03/29 23:46
55F:→ don750421: 當初討論需求時,只有提到寫功能需求及傳入的參數... 03/29 23:47
56F:→ don750421: SO...這部分還在想有啥其他解法... 03/29 23:47
57F:→ Litfal: 你的UC一定不是單純的UI,包含了很多耗時作業 03/30 02:44
58F:→ Litfal: 基本上,WinForm不會違反Control就是由UI執行續建立與操作 03/30 02:44
59F:→ Litfal: 這個原則,否則會遇到很多麻煩。 03/30 02:45
60F:→ Litfal: 你要先把UI單純化:只是顯示資料與發起作業,把業務邏輯提 03/30 02:47
61F:→ Litfal: 到另外的類別裏,在那裡要開幾個線程隨便你。 03/30 02:48
62F:→ Litfal: 而不是希望建立新的的Thread來控制Control,並希望該控制 03/30 02:49
63F:→ Litfal: 項的工作都由這個Thread完成。 03/30 02:49
64F:→ Litfal: btw,如果你是遇到UI更新頻率太高(如LOG太多)而卡死的問題 03/30 02:51
65F:→ Litfal: 那是需要別的手段優化。想用TextBox直接顯示LOG MESSAGE 03/30 02:52
66F:→ Litfal: 那個串接起來的字串長度會蠻可怕的。 03/30 02:52
67F:→ cid1979: http://goo.gl/jJMqJ1 關鍵字.net cross thread delegate 03/30 05:32
68F:→ don750421: 我的UC很單純,屬於被動元件,Form引用dll,UC的任何 03/30 23:23
69F:→ don750421: 作都是由public的Method所觸發,像是其中一個功能就是 03/30 23:24
70F:→ don750421: Form呼叫UC,透過WebService抓取檔案,再透過UC呈現.. 03/30 23:25
71F:→ don750421: 沒有Hardcode任何流程,或是引用其他dll.. 03/30 23:26
72F:→ don750421: 至於L大提到的TextBox處理,我個人是有限制行數,超過 03/30 23:27
73F:→ don750421: 2000就從前面逐行刪除,應該不至於有您所提到的問題@@ 03/30 23:27
74F:→ don750421: 不過,另我好奇的是,今天嘗試使用其他物件來顯示Log.. 03/30 23:28
75F:→ don750421: ListBox和datagridview不會跳出跨執行緒的錯誤,為什麼 03/30 23:29
76F:→ don750421: 難道是這兩種物件背後有特別做甚麼手腳嗎?? 03/30 23:29
77F:→ Litfal: C#的string是immutable,如果你認為重串那兩千行不會造成 03/30 23:38
78F:→ Litfal: 額外開銷... 03/30 23:39
79F:→ Litfal: 如果你是把呼叫WebService的細節直接寫在UC裡面,這就是 03/30 23:41
80F:→ Litfal: 把業務邏輯寫在UC裡面。不過先不討論"寫在哪裡" 03/30 23:43
81F:→ Litfal: 你要全部透過UC的public method控制也沒關係,但流程應該 03/30 23:44
82F:→ Litfal: 是:uc method-> service method 03/30 23:46
83F:→ Litfal: service method done -> event -> UC ->update UI 03/30 23:47
84F:→ Litfal: service method裡面可以用非同步去做,這樣UI與其執行續就 03/30 23:48
85F:→ Litfal: 只負責發起工作與顯示資料,而不會被業務邏輯工作佔用 03/30 23:49
86F:→ Litfal: 既可以優化用戶體驗,也沒有必須要用其他執行續去建控制項 03/30 23:50
87F:→ yeo1987: 跨執行緒操作UI沒有跳出錯誤不代表你的程式是執行緒安全 03/31 00:28
88F:→ yeo1987: 的,沒處理好這塊,會有可能發生意料之外的錯誤…你程式 03/31 00:28
89F:→ yeo1987: 中公開的方法不需考慮被呼叫時是使用哪一個執行緒,甚至 03/31 00:28
90F:→ yeo1987: 你在方法內要再開幾個執行緒去抓資料都可以,同步、非同 03/31 00:28
91F:→ yeo1987: 步都可以;但在更新UI時,請回到UserControl所屬的直行 03/31 00:28
92F:→ yeo1987: 緒叫用。 03/31 00:28







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Tech_Job站內搜尋

TOP