c# - Async/Await with a WinForms ProgressBar -
i've gotten type of thing working in past backgroundworker, want use new async/await approach of .net 4.5. may barking wrong tree. please advise.
goal: create component long-running work , show modal form progress bar it's doing work. component handle window block interaction while it's executing long-running work.
status: see code below. thought doing until tried interacting windows. if leave things alone (i.e. don't touch!), runs "perfectly", if click on either window program hangs after long-running work ends. actual interactions (dragging) ignored though ui thread blocked.
questions: can code fixed easily? if so, how? or, should using different approach (e.g. backgroundworker)?
code (form1 standard form progressbar , public method, updateprogress, sets progressbar's value):
using system; using system.diagnostics; using system.threading; using system.threading.tasks; using system.windows.forms; namespace consoleapplication1 { class program { static void main(string[] args) { console.writeline("starting.."); var mgr = new manager(); mgr.goasync(); console.writeline("..ended"); console.readkey(); } } class manager { private static form1 _progressform; public async void goasync() { var owner = new win32window(process.getcurrentprocess().mainwindowhandle); _progressform = new form1(); _progressform.show(owner); await go(); _progressform.hide(); } private async task<bool> go() { var job = new longjob(); job.onprogress += job_onprogress; job.spin(); return true; } void job_onprogress(int percent) { _progressform.updateprogress(percent); } } class longjob { public event progressed onprogress; public delegate void progressed(int percent); public void spin() { (var = 1; <= 100; i++) { thread.sleep(25); if (onprogress != null) { onprogress(i); } } } } class win32window : iwin32window { private readonly intptr _hwnd; public win32window(intptr handle) { _hwnd = handle; } public intptr handle { { return _hwnd; } } } }
@stephencleary's answer correct. though, had make little modification answer behavior think op wants.
public void goasync() //no longer async blocks on appication.run { var owner = new win32window(process.getcurrentprocess().mainwindowhandle); _progressform = new form1(); var progress = new progress<int>(value => _progressform.updateprogress(value)); _progressform.activated += async (sender, args) => { await go(progress); _progressform.close(); }; application.run(_progressform); }
Comments
Post a Comment