c# - TargetInvokationException in Application.Run(new Form1()); -
i trying iterate through loop pressing start button , stop pressing stop button. using await task.run(() =>
works in expected manner. when press start button again, targetinvokationexception in application.run(new form1());
.
my code below
using system.threading; using system.threading.tasks; using system.windows.forms; namespace cancellationtest { public partial class form1 : form { private readonly synchronizationcontext synchronizationcontext; private datetime previoustime = datetime.now; cancellationtokensource cts = new cancellationtokensource(); public form1() { initializecomponent(); synchronizationcontext = synchronizationcontext.current; } private async void buttonclickhandlerasync(object sender, eventargs e) { button1.enabled = false; var count = 0; cancellationtoken token = cts.token; await task.run(() => { try { (var = 0; <= 5000000; i++) { token.throwifcancellationrequested(); updateui(i); count = i; } } catch (system.operationcanceledexception) { messagebox.show("canceled"); } }, token); label1.text = @"counter " + count; button1.enabled = true; } public void updateui(int value) { var timenow = datetime.now; if ((datetime.now - previoustime).milliseconds <= 50) return; synchronizationcontext.post(new sendorpostcallback(o => { label1.text = @"counter " + (int)o; }), value); previoustime = timenow; } private void button2_click(object sender, eventargs e) { cts.cancel(); } } }
can explain why happens , how resolve this.
can explain why happens
targetinvokationexception
wrapper type exception , main information contained in innerexception
property didn't show. looking @ code, operationcanceledexception
, caused passing canceled token task.run
.
in general should not reuse cancellationtokensource
instance - see the general pattern implementing cooperative cancellation model in remarks section of documentation.
also should protect try/catch
whole block, not task.run
body. , initialize involved state members @ beginning, , necessary cleanup @ end.
so correct code this:
private datetime previoustime; private cancellationtokensource cts; private async void buttonclickhandlerasync(object sender, eventargs e) { button1.enabled = false; var count = 0; previoustime = datetime.now; cts = new cancellationtokensource(); try { cancellationtoken token = cts.token; await task.run(() => { (var = 0; <= 5000000; i++) { token.throwifcancellationrequested(); updateui(i); count = i; } }, token); } catch (system.operationcanceledexception) { messagebox.show("canceled"); } { cts.dispose(); cts = null; } label1.text = @"counter " + count; button1.enabled = true; }
and make sure cancel
button enabled when cts != null
or check condition inside click handler in order avoid nre.
Comments
Post a Comment