none
SerialPort,同樣的程式架構,Winform可以跑,WPF卻會卡住? RRS feed

  • 問題

  • 請問一下大家,小弟我現在在寫多機接收
    參考了https://dotblogs.com.tw/billchung/archive/2012/02/05/67809.aspx
    以他程式碼架構,用WPF去撰寫程式
    但每次執行到一半程式都會卡住

    小弟不信邪,用了winform再寫一次測試
    發現winform可以很順的執行
    這讓我想跳入WPF的心情瞬間當到谷底阿~
    請問這是什麼原因? 

    兩支程式供大家看看
    https://drive.google.com/file/d/0B1ah_3-YHFXzZ09XcFZOTUVlbk0/view?usp=sharing
    https://drive.google.com/file/d/0B1ah_3-YHFXzemdvbEFlNm55Q1k/view?usp=sharing

    資料格式(AHRS+資料+@@=58byte)
    41 48 52 53 00 00 04 43 00 00 04 43 00 00 04 43 00 00 04 43 00 00 04 43 00 40 9C C6 00 00 04 43 00 00 04 43 00 00 04 43 00 00 04 43 00 00 04 43 00 00 04 43 00 00 04 43 40 40

    我是用VSPE開啟兩個虛擬Port,再用SerialPortTest.exe打入資料後模擬傳送/接收...

    2016年3月4日 上午 08:19

解答

  • (1) 寫通訊程式不會用這種 Tick 事件委派函式會跑在 UI 執行緒的 Timer (如 Forms.Timer, DispatcherTimer) , 這是你第一個應該要改變的地方, 不論是 Windows Forms 或 WPF 都一樣.

    (2) Thread 最好設定其 IsBackground 屬性為 true, 省得你主程式關閉後, 它還跑個沒完.

    (3) 如果 CPU 飆太高, 請在 ReceiveData 的 while 迴圈內加上小量的 Thread.Sleep.

    (4) DisplayData 的部分, 如果串接字串的速度很快, 請先在子執行緒串接完字串再使用 BeginInvoke 將值指派給 TextBox

    否則你有兩個執行緒不斷地在搶 UI thread

    (5) WPF 其實和 Windows Forms 在架構上有些許不同, 如果要用 WPF , 通常偏向於使用繫結的方式反應資料的變化, 而不是直接用指派值給屬性的方式.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    • 已標示為解答 kira20206 2016年3月7日 上午 01:47
    2016年3月4日 下午 06:08
    版主

所有回覆

  • (1) 寫通訊程式不會用這種 Tick 事件委派函式會跑在 UI 執行緒的 Timer (如 Forms.Timer, DispatcherTimer) , 這是你第一個應該要改變的地方, 不論是 Windows Forms 或 WPF 都一樣.

    (2) Thread 最好設定其 IsBackground 屬性為 true, 省得你主程式關閉後, 它還跑個沒完.

    (3) 如果 CPU 飆太高, 請在 ReceiveData 的 while 迴圈內加上小量的 Thread.Sleep.

    (4) DisplayData 的部分, 如果串接字串的速度很快, 請先在子執行緒串接完字串再使用 BeginInvoke 將值指派給 TextBox

    否則你有兩個執行緒不斷地在搶 UI thread

    (5) WPF 其實和 Windows Forms 在架構上有些許不同, 如果要用 WPF , 通常偏向於使用繫結的方式反應資料的變化, 而不是直接用指派值給屬性的方式.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    • 已標示為解答 kira20206 2016年3月7日 上午 01:47
    2016年3月4日 下午 06:08
    版主
  • (1) 寫通訊程式不會用這種 Tick 事件委派函式會跑在 UI 執行緒的 Timer (如 Forms.Timer, DispatcherTimer) , 這是你第一個應該要改變的地方, 不論是 Windows Forms 或 WPF 都一樣.

    (2) Thread 最好設定其 IsBackground 屬性為 true, 省得你主程式關閉後, 它還跑個沒完.

    (3) 如果 CPU 飆太高, 請在 ReceiveData 的 while 迴圈內加上小量的 Thread.Sleep.

    (4) DisplayData 的部分, 如果串接字串的速度很快, 請先在子執行緒串接完字串再使用 BeginInvoke 將值指派給 TextBox

    否則你有兩個執行緒不斷地在搶 UI thread

    (5) WPF 其實和 Windows Forms 在架構上有些許不同, 如果要用 WPF , 通常偏向於使用繫結的方式反應資料的變化, 而不是直接用指派值給屬性的方式.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    1.用Tick的事件是為了想要每秒掃描Port,是否有新的Port可以連線,如果要保留這功能,還有其他方法可以解決嗎?

    5.原來如此! 繫結這部分小弟再來爬文研究研究

    感謝Bill大回覆及指導,WPF第一次用,還有很多不懂的地方,有問題再向您請教囉^^

    2016年3月7日 上午 01:53
  • 用多緒的的 Timer , 例如 Threading.Timer, Timers.Timer

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。


    2016年3月7日 上午 06:26
    版主
  • 我想起來, 可以不要用 Timer, 直接 hook WIN32 API.

    http://iamtestingman.blogspot.tw/2012/04/auto-detect-serial-port-in-wpf-c.html


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2016年3月8日 下午 03:22
    版主
  • 不好意思這麼晚回覆,好像跟我一直沒認證有關~"~
    當天晚上有測試OK了,也嚐試用Bill大您說的hook方式,也可以用噢!^^
    2016年3月11日 上午 09:25