Threading

Hi all,
In my pocket pc applicaiton, I'm trying to send data from internal database on the pocket to a main database on a remote server.

Every thing is OK till I have communication problems (No internet, Server is down , low signal ,...).
Whn I have a prolem the pocket is locked while it recieves an exception there is a problem.

So, I separated the connection and sending data by a thread. Each thim I call the function SyncData() I call it with a thread T.
What about if the user call this function many times, then I'll get many threads run in the background. 

How I can control the background threads Is there a way to know how many copies are Is there away to know the thread state, if I loced then to "Kill it".

My big delema: How to manage the threads  
Please give me links for benefit materials to read and check what to do.

Best regards... 


Answer this question

Threading

  • JeremyBeauchamp

    Just to add a reference to my own take on it:

    Shutting worker threads down gracefully

    Jon



  • Wilco B.

    There are many ways to do it.  It sounds like in your case however that permitting the user to try the operation multiple times wouldn't really be a good idea.  Therefore I would recommend that you set up your code such that it doesn't support being called more than once.  Depending on your need you can either throw an InvalidOperationException or silently ignore the request.  I'm assuming in this case that your users are other developers.  For the UI I would disable any button or other control that permits the user to invoke the function multiple times. 

    As for controlling the threading I would recommend that you use the ThreadPool to manage the thread.  Alternatively you can create your own thread but it seems like the thread pool would be better in this case.  I would recommend that you store a flag somewhere (perhaps with the code that actually starts the thread) and set the flag to true while the thread is running.  When the thread finishes and you are notified (using whatever mechanism you use) then reset the flag.  The flag will need to be thread safe.  Whenever the user invokes the function that would normally start the thread you should check the flag first.  If it is set then either throw an exception or silently ignore the request.  If you are intending to throw an exception then you should also provide the user with a property or method that lets them check whether the request would succeed (i.e. the thread is not currently running) before invoking your function to avoid the overhead of an exception.

    private bool m_bRunning = false;

    public void StartProcess ( )
    {
       if (m_bRunning)
          throw new InvalidOperationException("Already running.");

       //Lock the flag so we are thread-safe
       lock(m_lck)
       {
          //Check again just in case (double check)
          if (m_bRunning)
             throw new InvalidOperationException("Already running.");

          //It is running now
          m_bRunning = true;

          //The thread is not running so start the thread
          ...
       };
    }

    public bool IsRunning
    {
       get { return m_bRunning; }
    }

    //In the code that determines that the thread has finished running do this
    {
       ...
       lock(m_lck)
       {
          m_bRunning = false;
       };

       ...
    }

    There are a couple of issues with the above code.  Firstly using a simple object lock is fast but does mean that you can have a dirty read.  This means that you could read the value of m_bRunning but it actually change before you get a chance to do anything with it.  For clients who might check the property before invoking StartProcess there is nothing they can do.  They'll still have to use a try-catch around the call but it will eliminate the majority of the times when this could occur.  In the above case locking the flag for reading and writing is overkill to me.  Secondly it is possible, although unlikely, that the user may request the process to start but it actually won't.  This would occur if the user checked the property, determined it was already running and therefore didn't call StartProcess.  However sometime after the user checked the property the thread completed and returned.  Again there is not much you can do here because it is a boundary case but it could happen.  Without using more advanced sync objects (which I wouldn't recommend here) there is not much you can do about it.

    As an aside if you do want to support multiple simultaneous requests then switch the boolean flag to a reference counted integer.  The process doesn't change otherwise.

    Michael Taylor - 12/11/05

  • DesaiSandeep

    Depending on the semantics of your application, you may want to enable cancellation and re-initation from another thread or just ignore multiple requests. Assuming that you permit cancellation, your background thread (thread pool or otherwise) should send an asynchronous request and wait on a response from the remote service or cancellation from another thread (probably your UI thread). You can send messages between threads using WaitHandles. For your cancellation, I would use a ManualResetEvent. Then you can wait on multiple objects via WaitHandle.WaitAny.

    Another option would be to start the operation synchronously and then use Thread.Interrupt from your UI thread, which throws a ThreadInterruptedException on the worker thread when the worker thread blocks. You'll want to read the caveats in the docs. (i.e. If the thread never blocks, the exception is never thrown.)

    Some good references to read on threading in .NET:

    What Every Dev Must Know About Multithreaded Apps
    http://msdn.microsoft.com/msdnmag/issues/05/08/Concurrency/default.aspx
    Programming the Thread Pool in .NET
    http://msdn.microsoft.com/library/default.asp url=/library/en-us/dndotnet/html/progthrepool.asp
    Background Worker implementation
    http://weblogs.asp.net/rosherove/articles/BackgroundWorker.aspx

  • Lai.jet

    Hi all,

    I'll explain my case again with more details:

    Let's say I make call the SyncData() from A,B,C locations in the code.

    A:  SyncData()

    B: SyncData()

    C: if (A:SyncData()  and B:SyncData() give a true result) then C:SyncData() .

    When the communication is OK, there are no problems. SyncData()  at A make the task quickly and B also then we arrive to C and make SyncData() successfully.

    The problem is with the communication problems I mentioned(server down,No internet, connection slowly...). This proccess takes lots of time and my users want to leave my application because of that.

    I can ignor the A,B SyncData()  after a period of time T. after T if there is no response then you can make C:SyncData()

    I hope I explain my situation well.

    Please help me.

    Best regards..

     


  • Threading