multithreading - c# events execution are thread safe? -


i read lot of event , threads discussion, of focus in "what happen" if unsuscribe event , try call later. question different...what happen if have process in thread fires event "i finish" in millisecond 1, , have process in thread b fires event "i finish" in millisecond 2.

both processes suscribed same method listen , handle event. so, c# has execute method handles event 2 times: 1 time event fired in thread a, , 1 time event fired thread b.

what happen?? c# locks method when "first event coming thread a" starts execution of method handles event, , unlock method when finish execution, allowing other waiting "events" execute method content??

or event fired thread start execution of method handles event, , 1 millisecond later event fired thread b start execution on same method wihtout notice method being executed other "process"???

im asking this, because want file writing in method catch event, if method can executed simultaneously (depending on when event fired), guess cannot here, since info on file mix between 2 processes writing same file @ same time (not valid information on file).

my code looks (a little bit long, sorry). please note not compile, sample show im doing:

 public partial class mainform : form {     ftpclientmanager client = null;      public mainform()     {         initializecomponent();     }      private void btnconnect_click(object sender, eventargs e)     {         connect(this.tbftpserver.text.trim());         this.lstlog.items.add("connected"); //this lstlog list box have list of downloaded files threads.     }      void connect(string urlstr)     {         try {             client = new ftpclientmanager();             //subscribe event             client.filedownloadcompleted += new eventhandler<filedownloadcompletedeventargs>(client_filedownloadcompleted);         }         catch (exception ex)         {             messagebox.show(ex.message);         }     }      void client_filedownloadcompleted(object sender, filedownloadcompletedeventargs e)     {         this.invoke(new eventhandler<filedownloadcompletedeventargs>(              client_filedownloadcompletedhandler), sender, e);     }      void client_filedownloadcompletedhandler(object sender, filedownloadcompletedeventargs e)     {         string log = string.format("{0} instance {5} download {1} {2} completed. length: {3} time: {4}. ",             datetime.now, e.serverpath, e.localfile.fullname, e.localfile.length, e.downloadtime, e.ftpinstance);          this.lstlog.items.add(log);     }      private void btndownload_click(object sender, eventargs e)     {         client.downloadfiles();     } }     public class ftpclientmanager {     ftpdownloadclient[] arraydownloadclient = new ftpdownloadclient[2];             public event eventhandler<filedownloadcompletedeventargs> filedownloadcompleted;      public void downloadfiles()     {         (int = 0; < 2; i++)         {             arraydownloadclient[i] = new ftpdownloadclient();             //subscribe event. each instance of ftpdownloadclient suscribe same event.             arraydownloadclient[i].filedownloadcompleted += new eventhandler<filedownloadcompletedeventargs>(downloadclient_filedownloadcompleted);         }          //download 1 set of files in thread         arraydownloadclient[0].downloadfiles(list_of_files_to_download);          //download set of files in thread b         arraydownloadclient[1].downloadfiles(another_list_of_files_to_download);     }      //in theory, method downloadclient_filedownloadcompleted executed instance of ftpdownloadclient     //running in either thread or thread b, whichever finish first downloading file.     //my question comes in execution of method.     //lets process in thread finish downloading , fires event.     //lets process in thread b finish downloading 1 millisecond after thread finish, fires event.     //how c# manage execution of downloadclient_filedownloadcompleted??     //does event coming thread lock method downloadclient_filedownloadcompleted, execute it, , when finish execution unlock method      //and allows event coming thread b start locking, processing, unlock ??     //or method executed "at same time" (1 millisecond difference) each event fired thread , thread b??     void downloadclient_filedownloadcompleted(object sender, filedownloadcompletedeventargs e)     {         this.onfiledownloadcompleted(e);     }      protected virtual void onfiledownloadcompleted(filedownloadcompletedeventargs e)     {         if (filedownloadcompleted != null)         {             //this fire event, main form catch             //again, fire can triggered process in thread or process in thread b             filedownloadcompleted(this, e);          }     } }  public class ftpdownloadclient {     public event eventhandler<filedownloadcompletedeventargs>              filedownloadcompleted;      public void downloadfiles(string [] files_to_download)     {         parameterizedthreadstart threadstart =                 new parameterizedthreadstart(startdownloadfiles);             thread downloadthread = new thread(threadstart);             downloadthread.isbackground = true;             downloadthread.start(new object[] { files_to_donwload });     }      //this metod download files in list passed parameter.     //every file downloaded raise event filedownloadcomplete, message can added lstlog on main form     void startdownloadfiles(object state)         {             var paras = state object[];              string [] files = paras[0] string [];              foreach (var file in files)             {                 downloadonefile(file);             }         }       void downloadfile(string onefile)      {             //donwload file done here             var filedownloadcompletedeventargs = new filedownloadcompletedeventargs             {                localfile = new fileinfo(destpath),                serverpath = onefile,                downloadtime = filedownloadtime.elapsedmilliseconds.tostring()             };              this.onfiledownloadcompleted(filedownloadcompletedeventargs);      }       protected virtual void onfiledownloadcompleted(filedownloadcompletedeventargs e)         {             if (filedownloadcompleted != null)             {                 //the event fired when file being downloaded thread finish.                 //so, thread fire event current thread                 //and thread b fire same event own thread.                 filedownloadcompleted(this, e);              }         } } 

c# not doing locking you. if events can raised multiple threads simultaneously, must write code handle (if necessary).

you can use lock statement prevent multiple threads executing it:

private void myeventhandler(object sender, eventargs e) {     lock (lockingobject)     {         // handle event here.         // 1 thread @ time can reach code.     } } 

where lockingobject field inside class declared like:

private readonly object lockingobject = new object(); 

you have careful threading in method raises event.

suppose have event in class called myevent. should not this:

private void raisemyevent() {     if (myevent != null)                  // {1}         myevent(this, new eventargs());   // {2} } 

if thread can detach myevent, it's possible detach between line {1} , line {2}. if happens, line {2} throw null reference exception because myevent have become null!

the correct way is:

private void raisemyevent() {     var handler = myevent;      if (handler != null)          handler (this, new eventargs());  } 

now null reference exception can't happen.

however, note when using multiple threads it's possible event handler called after thread has detached it!


Popular posts from this blog

How to calculate SNR of signals in MATLAB? -

c# - Attempting to upload to FTP: System.Net.WebException: System error -

ios - UISlider customization: how to properly add shadow to custom knob image -