日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何安全使用SWT的显示器asyncExec

發(fā)布時間:2023/12/3 编程问答 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何安全使用SWT的显示器asyncExec 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

大多數(shù)用戶界面(UI)工具包都是單線程的, SWT也不例外。 這意味著必須僅從單個線程(即所謂的UI線程)訪問UI對象。 另一方面,應(yīng)在后臺線程中執(zhí)行長時間運(yùn)行的任務(wù),以使UI保持響應(yīng)。 這使得后臺線程需要排隊在UI線程上執(zhí)行更新,而不是直接訪問UI對象。

為了安排代碼在UI線程上執(zhí)行,SWT提供了Display asyncE?xec()和syncE?xec()方法。

顯示asyncE?xec與syncE?xec

雖然這兩種方法都將參數(shù)放在隊列中以便在UI線程上執(zhí)行,但是它們在執(zhí)行(或不執(zhí)行)之后的操作不同。 顧名思義,asyncE?xec()異步工作。 它在可運(yùn)行變量入隊后立即返回,并且不等待其執(zhí)行。 而syncE?xec()處于阻塞狀態(tài),因此確實要等到代碼執(zhí)行完畢。

根據(jù)經(jīng)驗,只要不依賴計劃代碼的結(jié)果即可使用asyncE?xec(),例如僅更新小部件以報告進(jìn)度。 如果計劃的代碼返回了與進(jìn)一步控制流相關(guān)的內(nèi)容(例如,在阻止對話框中提示輸入),那么我將選擇syncE?xec()。

例如,如果后臺線程想要報告已完成工作的進(jìn)度,則最簡單的形式可能如下所示:

progressBar.getDisplay().asyncE?xec( new Runnable() {public void r?un() {progressBar.setSelection( ticksWorked );} } );

asyncE?xec()計劃“在下一個合理的機(jī)會”(如JavaDoc所說)在UI線程上執(zhí)行可運(yùn)行對象。

不幸的是,上面的代碼可能會不時地失敗,并會出現(xiàn)一個放置小部件的異常 ,或更確切地說是一個SWTException,其代碼== SWT.ERROR_WIDGET_DISPOSED。

因此,原因是,進(jìn)度條在被訪問時可能不再存在(即,調(diào)用setSelection())。 盡管我們?nèi)匀槐A糁鴮π〔考囊?#xff0c;但是由于小部件本身已被廢棄,因此并沒有太大用處。 解決方案顯而易見:代碼必須首先測試該小部件是否仍然存在,然后再對其進(jìn)行操作:

progressBar.getDisplay().asyncE?xec( new Runnable() {public void r?un() {if( !progressBar.isDisposed() ) {progressBar.setSelection( workDone );}} } );

看起來很明顯,一次又一次地執(zhí)行這種檢查是很乏味的。 您可能想在Eclipse bugzilla中搜索“ widget處置”,以了解此問題的發(fā)生頻率。 因此,我們提取了一個封裝檢查的輔助類。

new UIThreadSynchronizer().asyncE?xec( progressBar, new Runnable() {public void r?un() {progressBar.setSelection( workDone );}} );

UIThreadSynchronizers asyncE?xec()方法期望將小部件作為其第一個作為上下文的參數(shù)。 上下文小部件是指如果可運(yùn)行的部件多于一個,則將受可運(yùn)行部件或合適的父部件影響的部件。 在運(yùn)行runnable之前,將檢查上下文小部件。 如果仍然有效(即未處置),則將執(zhí)行代碼,否則,將靜默刪除該代碼。 盡管忽略已處置小部件的代碼的行為可能看起來很粗心,但它適用于到目前為止我們遇到的所有情況。

進(jìn)行線程間通信的單元測試代碼特別難以測試。 因此,盡管UIThreadSynchronizer是無狀態(tài)的,但必須對其進(jìn)行實例化以使其可以通過test double替換。

  • 帶有相應(yīng)測試的源代碼可以在這里找到: https : //gist.github.com/rherrmann/7324823630a089217f46

盡管示例使用了asncE?xec(),但UIThreadSynchronizer也支持syncE?xec()。 并且,當(dāng)然,helper類也與RAP / RWT兼容。

如果您完整地閱讀了源代碼,您可能已經(jīng)注意到可能存在爭用情況。 因為Widget類的所有方法都不是線程安全的,所以isDisposed()或getDisplay()返回的值可能是陳舊的(請參見第51 行和第60行 )。 當(dāng)時故意將其忽略-閱讀:我沒有找到更好的解決方案。 盡管runnable可能會被錯誤地排入隊列,但是isDisposed()-check(在UI線程上執(zhí)行)將最終阻止代碼執(zhí)行。

剩下的線程問題還有另一個(絕對是很小的)機(jī)會:恰好在調(diào)用(a)syncEecxec()之前,檢查顯示器的處置方式,以免發(fā)生小部件處置異常。 但是,如果將顯示放置在檢查和(a)syncE?xec()的調(diào)用之間,則可能會發(fā)生這種情況。 盡管可以通過將調(diào)用包裝到忽略小部件處理的異常的try-catch塊中來解決asyncE?xec()的問題,但對syncE?xec()而言,相同的方法將失敗。 無法通過合理的努力將可運(yùn)行對象引發(fā)的SWTException與syncE?xec()引發(fā)的SWTException區(qū)別開來。

翻譯自: https://www.javacodegeeks.com/2014/09/how-to-safely-use-swts-display-asyncexec.html

總結(jié)

以上是生活随笔為你收集整理的如何安全使用SWT的显示器asyncExec的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。