c# - Detect Boolean value changes inside Thread -


i have c++ dll function want run inside c# thread.

some times need cancel thread, , here issue :

thread.abort() evil multitude of articles i've read on topic

the way use bool , check it's value periodically.

my problem set value true didn't change , still equal false in c++ code. when show messagebox value changed , works fine. ideas why value changed when messagebox showed , please tell me how fix issue. c#

 public void abortmesh()         {              if (currmeshstruct.value.meshthread != null && currmeshstruct.value.meshthread.isalive)             {              //here c++ object , cancel mesh used set bool true;                                 meshcreator.cancelmesh();             }         } 

c++

stdmethodimp meshcreator::cancelmesh(void) {     this->m_stopmesh = true;     return s_ok; } 

when test boolean value

if (m_stopmesh)     return s_false; 

the value here false call abortmesh()

if (m_stopmesh)         return s_false;   messagebox(null,amessage,l"test",null);   if (m_stopmesh) // here value changed true          return s_false; 

the non-deterministic thread abortion (like thread.abort) bad practice. problem is practice allows stop job when job not know stopped.

there no library or framework in .net know of allows write threaded code allow run arbitrary task , abort @ time without dire consequences.

so, write when decided use manual abort using synchronization technique.

solutions:

1) simplest 1 using of volatile boolean variable suggested:

c#

public void abortmesh()         {              if (currmeshstruct.value.meshthread != null && currmeshstruct.value.meshthread.isalive)             {                                 meshcreator.cancelmesh();             }         } 

c++/cli

public ref class meshcreator {      private:         volatile system::boolean m_stopmesh;     ... }  stdmethodimp meshcreator::cancelmesh(void) {     this->m_stopmesh = true;     return s_ok; }  void meshcreator::processmesh(void) {     int32 processedparts = 0;      while(processedparts != totalpartstoprocess)     {         continueprocessing(processedparts);         processedparts++;          if (this->m_stopmesh)         {             this->makecleanup();             messagebox(null,amessage,l"test",null);         }           }  } 

such code should not require synchronization if not make assumptions on completion of thread after cancelmesh call - not instantaneous , may take variable amount of time happen.

i don't know why use of volatile didn't you, there few moments check:

  1. are sure meshcreator.cancelmesh(); method call happen?
  2. are sure m_stopmesh initialized before actual processing begins?
  3. are sure check variable inside processmesh enough have decent response time worker , not expecting instantaneous?

2)also if use .net 4 or higher try use cancellationtoken-cancellationtokensource model. designed work tasks model works standard threads. won't simplify code taking account async nature of processing code possibly simplify future integration tpl

 cancellationtokensource canctokensource = new cancellationtokensource();  cancellationtoken canctoken = canctokensource.token;   thread thread = new thread(() =>  {      int32 iteration = 0;      while (true)      {          console.writeline("iteration {0}", iteration);          iteration++;          thread.sleep(1000);          if (canctoken.iscancellationrequested)              break;       }   });    thread.start();    console.writeline("press key cancel...");   console.readkey();   canctokensource.cancel(); 

3) may want read interlocked class,monitor locks, autoresetevents , other synchronization, not needed in application

edit:

well, don't know how couldn't help(it not best idea, should work such scenario), i'll try later mock app , check issue - possibly has how msvc , csc handle volatile specifier.

for try use interlocked reads , writes in app:

public ref class meshcreator {      private:         system::boolean m_stopmesh;     ... }  stdmethodimp meshcreator::cancelmesh(void) {     interlocked::exchange(%(this->m_stopmesh), true);     return s_ok; }  void meshcreator::processmesh(void) {     int32 processedparts = 0;      while(processedparts != totalpartstoprocess)     {         continueprocessing(processedparts);         processedparts++;          if (interlocked::read(%(this->m_stopmesh))         {             this->makecleanup();             messagebox(null,amessage,l"test",null);         }           }  } 

p.s.: can post code processes data , checks variable(i don't mean full meshes calculations method, main stages , elements)?

edit: @ least it's clear system about

it possible child processes not exterminated quick enough. read this thread process killing.

p.s.: , edit question more describe system , problem. difficult right answer wrong or incomplete question.


Comments

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

Python ctypes access violation with const pointer arguments -