none
Porblem while implementing multi-threading in C# RRS feed

  • Question

  • hi,

    I am using multi-threading in my application.Consider a simple example

    I have one file upload control and submit button

    on click of submit button first i am saving it to my local drive and than i am creating a background thread to upload content to my server and deleting local files

     private void SaveUpdatePhotoGallery()
        {
            try
            {
                //Guid guid = Guid.NewGuid();
                Model model=new Model();
                if (fuIcon.HasFile)
                {
                    HttpPostedFile file = Request.Files[0];
                    System.Guid guid = System.Guid.NewGuid();
                    string fileName = "ic" + guid.ToString() + ".png";
                    string thumbnail = "tb" + guid.ToString() + ".png";
                    string loResFile = "lo" + guid.ToString() + ".png";
                    file.SaveAs(saveLocation + "/" + fileName);
                    model.IconUrl = urlBase + "/" + fileName;
                    //Common.ResizeImageRation(saveLocation + "/" + fileName, saveLocation + "/" + thumbnail, 57, 57);
                    //Common.LowResolutionImage(saveLocation + "/" + fileName, saveLocation + "/" + loResFile);
                }

                if (ModelController.Create(model))
                {
                 
                    model.Id = ModelController.GetMaxPhotoGalleryId();           
                    Thread UploadThread = null;
                    UploadThread = new Thread(() =>
                   {
                       try { UploadImageToServer(model); }
                       catch (ThreadAbortException tae) { UploadThread.Abort(); }

                   });
                    {
                        UploadThread.Start();
                        UploadThread.IsBackground = true;                  
                    }
                }
            }
            catch (IOException e)
            {
            
            }     
        }

    This is my thread code:

     protected void UploadImageToServer(Model model)
        {
            lock (locker)
            {
                if (model!= null)
                {


                    if (File.Exists(AppSettings.SaveImageDiskUrl + Path.GetFileName(model.IconUrl)))
                    {
                       

                         //this function checks whether file is used by another process if so than it would sleep otherwise will run.

                        if (!FileInUse(AppSettings.SaveImageDiskUrl + Path.GetFileName(model.IconUrl)))
                        {
                            BucketHelper.PutFile(AppSettings.ServerPhotoFolder, Path.GetFileName(model.IconUrl), AppSettings.SaveImageDiskUrl);
                            model.IconUrl = AppSettings.SaveServerPhotoUrl + Path.GetFileName(model.IconUrl);
                            File.Delete(AppSettings.SaveImageDiskUrl + Path.GetFileName(model.IconUrl));
                        }
                        else
                        {
                            Thread.Sleep(1000);
                        }
                    }

                    if (ModelController.UpdateIconUrl(model.IconUrl, model.CId))
                    {

                    }
                }
            }
        }

    so i want my thread to sleep for sometime if image is being used by other process if so than it would wait for that process to release it and again call this function.What i am having is that mythread is not going in wait state on call of that because its not getting call after 1000 millisec.

    Wednesday, May 9, 2012 12:45 PM

Answers

  • Yes and no. In general there's no way to "call" a particular thread after a specific time interval.

    Yer (http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx) that with the interval set to 1000ms and callback function set to UploadImageToServer. Once the timer is setup you can return from UploadImageToServer and this will cause the thread to exit. One the timer fires it will call UploadImageToServer on a thread taken from the thread pool.

    Wednesday, May 9, 2012 1:54 PM
    Moderator
  • Mike Danes is on the right track.  You'll want to have a loop running on its own thread (not the UI thread) that looks like this (in pseudocode)

    void YourFunction()
    {
       for( int attempts = 0; attempts < maxAttempts; ++attempts )
       {
          if( DoSomething() )
             return;
          else
             GetReadyToTryAgain();
       }
       throw new Exception( "max attempts exceeded" );
    }
    
    void GetReadyToTryAgain()
    {
       // Possibly take other measures here to ensure that
       // a subsequent DoSomething will succeed.
       // At least wait a little while.
       Thread.Sleep(1000);
    }
    
    bool DoSomething()
    {
       lock( obj )
       {
          // Take a swing at it here.
          ...
          if( successful ) 
             return true;
          else
             return false;
       }
    }
    

    Wednesday, May 9, 2012 2:11 PM
  • I think this is what they are saying to do:

    protected void UploadImageToServer(Model model)
         {
             lock (locker)
             {
                 if (model!= null)
                 {
     
    
                    if (File.Exists(AppSettings.SaveImageDiskUrl + Path.GetFileName(model.IconUrl)))
                     {
                        
     
                         //this function checks whether file is used by another process if so than it would sleep otherwise will run.
     
                        if (!FileInUse(AppSettings.SaveImageDiskUrl + Path.GetFileName(model.IconUrl)))
                         {
                             BucketHelper.PutFile(AppSettings.ServerPhotoFolder, Path.GetFileName(model.IconUrl), AppSettings.SaveImageDiskUrl);
                             model.IconUrl = AppSettings.SaveServerPhotoUrl + Path.GetFileName(model.IconUrl);
                             File.Delete(AppSettings.SaveImageDiskUrl + Path.GetFileName(model.IconUrl));
                         }
                         else
                         {
                             Thread.Sleep(1000);
                             UploadImaageToServer(Model);
                             // better put a retry timeout here
    
    
                         }
                     }
     
    


    JP Cowboy Coders Unite!

    Wednesday, May 9, 2012 3:35 PM

All replies

  • "its not getting call after 1000 millisec."

    A thread is not "called" after 1000 milliseconds, after that interval expires Sleep returns and the thread continues executing as normal. That means that you need to have some sort of loop in your code that allows it to retry the file writing code. You don't seem to have such a loop in your code.

    Wednesday, May 9, 2012 1:38 PM
    Moderator
  • "its not getting call after 1000 millisec."

    A thread is not "called" after 1000 milliseconds, after that interval expires Sleep returns and the thread continues executing as normal. That means that you need to have some sort of loop in your code that allows it to retry the file writing code. You don't seem to have such a loop in your code.

    i got what your are trying to tell but is there any inbuilt function that can call my function again instead of loop which can call by my function after sometime if myfile is in use
    Wednesday, May 9, 2012 1:46 PM
  • Yes and no. In general there's no way to "call" a particular thread after a specific time interval.

    Yer (http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx) that with the interval set to 1000ms and callback function set to UploadImageToServer. Once the timer is setup you can return from UploadImageToServer and this will cause the thread to exit. One the timer fires it will call UploadImageToServer on a thread taken from the thread pool.

    Wednesday, May 9, 2012 1:54 PM
    Moderator
  • Mike Danes is on the right track.  You'll want to have a loop running on its own thread (not the UI thread) that looks like this (in pseudocode)

    void YourFunction()
    {
       for( int attempts = 0; attempts < maxAttempts; ++attempts )
       {
          if( DoSomething() )
             return;
          else
             GetReadyToTryAgain();
       }
       throw new Exception( "max attempts exceeded" );
    }
    
    void GetReadyToTryAgain()
    {
       // Possibly take other measures here to ensure that
       // a subsequent DoSomething will succeed.
       // At least wait a little while.
       Thread.Sleep(1000);
    }
    
    bool DoSomething()
    {
       lock( obj )
       {
          // Take a swing at it here.
          ...
          if( successful ) 
             return true;
          else
             return false;
       }
    }
    

    Wednesday, May 9, 2012 2:11 PM
  • I think this is what they are saying to do:

    protected void UploadImageToServer(Model model)
         {
             lock (locker)
             {
                 if (model!= null)
                 {
     
    
                    if (File.Exists(AppSettings.SaveImageDiskUrl + Path.GetFileName(model.IconUrl)))
                     {
                        
     
                         //this function checks whether file is used by another process if so than it would sleep otherwise will run.
     
                        if (!FileInUse(AppSettings.SaveImageDiskUrl + Path.GetFileName(model.IconUrl)))
                         {
                             BucketHelper.PutFile(AppSettings.ServerPhotoFolder, Path.GetFileName(model.IconUrl), AppSettings.SaveImageDiskUrl);
                             model.IconUrl = AppSettings.SaveServerPhotoUrl + Path.GetFileName(model.IconUrl);
                             File.Delete(AppSettings.SaveImageDiskUrl + Path.GetFileName(model.IconUrl));
                         }
                         else
                         {
                             Thread.Sleep(1000);
                             UploadImaageToServer(Model);
                             // better put a retry timeout here
    
    
                         }
                     }
     
    


    JP Cowboy Coders Unite!

    Wednesday, May 9, 2012 3:35 PM
  • Did you know that the experts for C# live in the C# forum. Although everthing in .Net is related to the base class, it that alike you ask questions in a Cro-Magnon forum if you want to know what is on television in New York tonight. 

    http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/threads


    Success
    Cor

    Thursday, May 10, 2012 7:00 AM