[問題] 請教BackgroundWorker轉Async Await?

看板C_Sharp (C#)作者 (VAIO)時間9年前 (2016/01/02 10:22), 編輯推噓0(0041)
留言41則, 3人參與, 最新討論串1/2 (看更多)
請教一下版上前輩, 小弟有件舊方案使用BackgroundWorker, 打算用Async-Await搭Task的方式重寫. 目前遇到一個問題就是, 原本的寫法會在RunWorkerCompleted 的最後再去呼叫一次RunWorkerAsync觸發DoWork, 在背景一直循環. 如果要用Async-Await-Task的寫法, 要怎麼達到同樣的效果? 我現在是把整個流程包成一個Method用按鍵Click去觸發, 如果我用 迴圈類的架構去包, 又會變成UI freeze.. 不知道有沒有對應RunWorkerAsync及RunWorkerCompleted的Method? -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.36.78.139 ※ 文章網址: https://www.ptt.cc/bbs/C_Sharp/M.1451701366.A.A05.html

01/02 11:29, , 2F
或是用System.Threading.Timer做
01/02 11:29, 2F

01/02 11:29, , 3F
Timer timer = new Timer(t =>
01/02 11:29, 3F

01/02 11:29, , 4F
{
01/02 11:29, 4F

01/02 11:29, , 5F
//Do something here
01/02 11:29, 5F

01/02 11:30, , 6F
((Timer)t).Change(0, Timeout.Infinite);
01/02 11:30, 6F

01/02 11:30, , 7F
});
01/02 11:30, 7F

01/02 11:30, , 8F
timer.Change(0, Timeout.Infinite);
01/02 11:30, 8F

01/02 11:31, , 9F
不然就是回歸傳統用Thread 如果要換掉BackgroundWorker話
01/02 11:31, 9F

01/02 14:49, , 10F
既然要循環為什麼不用無窮迴圈?
01/02 14:49, 10F

01/02 14:51, , 11F
另外Task有ContinueWith,還有你的需求乍看下不適合用
01/02 14:51, 11F

01/02 14:52, , 12F
await去取代
01/02 14:52, 12F

01/02 15:09, , 13F
單純用無窮迴圈會卡死UI 所以他需要後台執行
01/02 15:09, 13F

01/02 15:10, , 14F
ContinueWith應該很難寫成無窮 Task內無限迴圈比較合理
01/02 15:10, 14F

01/02 15:12, , 15F
...當然不可能單純無窮迴圈阿...以他提供的資訊來看,用
01/02 15:12, 15F

01/02 15:12, , 16F
RunWorkerCompleted再啟動就是ContinueWith阿
01/02 15:12, 16F

01/02 15:13, , 17F
await該Task即可 不然就是Thread內迴圈或Timer了
01/02 15:13, 17F

01/02 15:13, , 18F
無窮迴圈是一種寫法,並沒有說要在UI Thread上跑好嗎...
01/02 15:13, 18F

01/02 15:14, , 19F
以文中的寫法 ContinueWith 再啟動同一件事不好寫吧?
01/02 15:14, 19F

01/02 15:15, , 20F
是啊 原PO只要解決不在UI thread上跑無窮迴圈就行了
01/02 15:15, 20F

01/02 15:15, , 21F
await無窮迴圈的Task...?那await後面的東西永遠不會跑...
01/02 15:15, 21F

01/02 15:16, , 22F
所以我貼的連結是有CancellationToken的
01/02 15:16, 22F

01/02 15:17, , 23F
對,所以我劈頭第一句就問為什麼不用無窮迴圈要用
01/02 15:17, 23F

01/02 15:17, , 24F
BackgroundWorker了,我猜他每次工作一次就要回傳一些進度
01/02 15:17, 24F

01/02 15:17, , 25F
顯示在UI上
01/02 15:17, 25F

01/02 15:17, , 26F
如果他Cancel了 就會回await了
01/02 15:17, 26F

01/02 15:18, , 27F
嗯 這也有可能
01/02 15:18, 27F

01/02 15:22, , 28F
如果還是要Task內迴圈 實作IProgress是好主意嗎?
01/02 15:22, 28F

01/02 15:38, , 29F
先看看原PO為什麼要用BackgroundWorker吧
01/02 15:38, 29F

01/02 19:02, , 30F
兩位先進請恕小弟沒有講明白, 實際的Task是一個Query遠端
01/02 19:02, 30F

01/02 19:04, , 31F
SQL資料庫並轉換成報表到UI的動作, 每隔半小時觸發一次
01/02 19:04, 31F

01/02 19:06, , 32F
原本timer是寫在BgWorker的complete裡面
01/02 19:06, 32F

01/02 19:07, , 33F
因為這是在公司用的code, 有點敏感不方便貼, 不好意思.
01/02 19:07, 33F

01/02 19:18, , 34F
task.continue with也是目前考慮的方向. Task內無窮迴圈
01/02 19:18, 34F

01/02 19:20, , 35F
的寫法因為有牽扯到回傳UI, 實際運行會UI freeze?
01/02 19:20, 35F

01/02 19:23, , 36F
總之,感謝兩位的回覆. 我會重寫那段方法再試, 現在是co的
01/02 19:23, 36F

01/02 20:45, , 37F
你想換掉原有BgWorker的原因是?
01/02 20:45, 37F

01/02 20:49, , 38F
因為我們新專案都用Async了, 為了align新人的SOP.
01/02 20:49, 38F

01/02 20:50, , 39F
Forms的Timer能用吧?我覺得你的需求最簡單的解決方式是
01/02 20:50, 39F

01/02 20:51, , 40F
用Timer觸發定時,去Call Query Method,如果Query不複雜
01/02 20:51, 40F

01/02 20:53, , 41F
甚至不用Async。耗時的話就把Query method寫成Async版本
01/02 20:53, 41F
文章代碼(AID): #1MXpHse5 (C_Sharp)
文章代碼(AID): #1MXpHse5 (C_Sharp)