c# - Cancellation async in IDisposable class -
in project use manager control plugin. main idea plugin must work in single thread in multythreads wpf application. there 1 instance of plugin in plugincontroller.
so when call start method: stops plugin (if running) , start new argument. few times second plugin notificate caller it's state, , viewmodel shows in wpf window.
when call method start times 1 after one, see previous instance of viewmodel not destroyed, sleeps after stop. , calls update method god new 1 instance. interface twiches becouse 2 instances updating it's state. in log see alternately lines first 1 , second one.
but when call start(...) stop() , start(...) again works fine.
so
somemanager.start(...); somemanager.start(...);
works errors. and
somemanager.start(...); somemanager.stop(); somemanager.start(...);
works fine. can explain me mistake?
down lied simplified code.
public static somemanager { public static void start(somearg arg) { stop(); // forgotten code var vm = getmainpagevm(); vm.somevm = new someviewmodel(arg); vm.somevm.startcommand.execute(null); } public static void stop() { var vm = getmainpagevm(); if (vm.somevm != null) { vm.somevm.stop(); vm.somevm.dispose(); vm.somevm = null; } } } public sealed someviewmodel : viewmodelbase, idisposable { private readonly guid _guid = guid.newguid(); private iplugin _plugin; private somearg _arg; public icommand startcommand {get; } public cancellationtokensource source {get; } public someviewmodel(somearg arg) { this._arg = arg; this._plugin = plugincontroller.getpluginbyname("someplugin"); startcommand = new relaycommand(startasync); } ~someviewmodel() { dispose(false); } public void dispose() { dispose(true); gc.suppressfinalize(this); } private void dispose(bool disposing) { ... } private async task startasync() { var progress = new progress<isomeprogress>(update); try { await startimplementationasync(progress).configureawait(false); } catch (exception e) { ... } } private async task startimplementationasync(progress<isomeprogress> progress) { var result = await this._plugin.startasync( this._arg, progress, this.source.token ).configureawait(false); } public void stop() { this._plugin.stop(); } private void update() {log.debug($"this._guid" ....); } } public sealed someplugin: iplugin { public async task<someresult> startasync(somearg args, iprogress<someprogress>, cancellationtoken cancellationtoken) { ... } public void stop() { ... } }
update: think problem in simple words : how correctly cancel async operation in idisposable object in normal case cancellationtokensource.cancel() , in unnormal case when dispose() or finalizer called
Comments
Post a Comment