Click here to Skip to main content
15,867,453 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello,

My C# application contains a BackgroundThread. I am on a stage that on an event I got to call a method (that Runs bgworker) untill the process is successful. And if an error is occured then stop the loop.

C#
public void DisconnectEvent() {
      ......
    // START THE  reconnect Thread 
    reconnectThread = new Thread(new ThreadStart(TryConnect));
    reconnectThread.Start();
}

// Tries to connect untill its successful or an error has raised
private void TryConnect()
{
    Logger.LogInfo("Into Trying to Connect : connected = " + connected);
    while (connected == false)
    {
        Logger.LogInfo("Into TryConnect : While.. Going");
        currentState = RECONNECTING;
        // Try again after 20 secs
        Thread.Sleep(20000);
        if (!UltimateLibrary.http.HTTPUtility.isConnectionAvailable()) {
            Thread.Sleep(10000);
            continue;
        }
        Logger.LogInfo("Into TryConnect : About to start connecting ");
        ConnectClicked();
        Logger.LogInfo("Into TryConnect : Finished ConnectClicked  && connected = " + connected);
        if (connected)
            break;
    }
}

private void ConnectClicked() {
    ....
    backgroundWorker1.RunWorkerAsync();  // This call Connect
    ..... // Set message
    Logger.LogInfo("Finished ConnectClicked");
}

private void Connect() {
    try {
       ....
       Logger.LogInfo("Got Server Config : " );
       ....
       Logger.LogInfo("Starting to Connect");
       ......   
    } catch(Exception e) {
       // HERE SINCE EXCEPTION IS CAUGHT THE 
       // TryConnect() SHOULD BE STOPPED

       reconnect.Abort();    
    }
}


Above is the code and how I want to happen. The output with above code is :
14-06-2011 16:08:27 ==> INFO : Into Trying to Connect : connected = False
14-06-2011 16:08:27 ==> INFO : Into TryConnect : Again in While.. Going to sleep
14-06-2011 16:08:48 ==> INFO : Into TryConnect : About to start connecting
14-06-2011 16:08:48 ==> INFO : Finished ConnectClicked
14-06-2011 16:08:48 ==> INFO : Into TryConnect : Finished ConnectClicked  && connected = False
14-06-2011 16:08:48 ==> INFO : Into TryConnect : Again in While.. Going to sleep
14-06-2011 16:08:50 ==> INFO : GOT Server Config :True
14-06-2011 16:08:50 ==> INFO : Starting to Connect
 ERROR Occured & reconnectThread is Aborted


The 5th line in log "Into TryConnect : Finished ConnectClicked " should come after whole process of ConnectClicked() is completed.

I can use MethodInvoker delagate & then Invoke it. But then how do I stop it on excption caught.

I don't know how to handle this part synchronously. Can anyone help me.
Please am in ahurry.


Thanks
Posted

To communicate with another thread, you need to use mutexes, wait handles or messages sent between them. However, as SA says, it is a Bad Idea to wait on network information, because it can freeze your application indefinitely.

To do something when a background worker successfully (or otherwise) completes, look at BackgroundWorker.RunWorkerCompleted[^]. Note that this is marshalled into the UI thread and therefore if you are running a non-UI based application it can have problems.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 14-Jun-11 12:35pm    
That's correct, my 5, only mutex is just for access for shared resources (yes, one of the most important tasks), but a lock would do it, too; for performance, upgreadable ReaderWriterLockSlim can be better, for these reason Mutex is not often used (for threads of the same process, it's more for IPC).
--SA
BobJanova 14-Jun-11 14:53pm    
Yeah, locks are a common way to communicate between threads though. Not appropriate in this case, probably! I didn't mean the Mutex class specifically, but the various related items that you mentioned. So thanks for improving the answer!
As the bobJanova wrote, use of BackgroundWrokder is much useful then using thread, when you want some call back or some notification.
see this link
more links...
Link1[^]
Link2[^]
 
Share this answer
 
Comments
All Time Programming 15-Jun-11 4:12am    
Thanks to all of you. My app is a UI clirnt and I already use BackgroundWorker thread for all activities. The current case is, if the connection is lost, I want to try connecting untill suceeds or an erro occured. Maybe I call background thread for reconnecting, in RunCompleted how to make it call recursively untill a variable (connected) is set to true.
Do you say that in RunCompleted, I check the variable and if its false, call another mthod that inturn calls/starts backgroundthread ? And if error is raised the background thread is cancelled any ways.
Is this true by what I understand you experts are trying to say !
All Time Programming 16-Jun-11 8:13am    
Was in full confusion for whose answer to Accept ! Voted 5 for each answer. But as Member_6499766 had lowest score from you 3 and his answer was to point, so accepted his. Solutions of 3 of you are right and appropriate to great extend. Thanks to all of you. Thanks.
parmar_punit 16-Jun-11 9:27am    
Thanks,
Please see my another solution No.4 that gives you an idea to work with BackGroundWorker...
You need to put all your networking code in a separate thread, not just connection. The idea is simple. You have to do so with any processing which takes time, especially with blocking calls such as most of networking operations.

You need to catch all exceptions at the top of stack of each thread, to prevent uncontrolled termination. At the same time you should not leave this code without any action. As a minimum, you need to log exception information or show it in UI. This rule have some exceptions for pretty rare cases. With networking, you may also need to do it in cycle, to recover from previous exceptions.

See more detail in my past answers:
How do i make a loop that will stop when a scrollbar reaches the bottom[^],
When i run an application an exception is caught how to handle this?[^],
throw . .then ... rethrowing[^].

You're writing code in client side where you may need just one other thread. On server part you need to create at least two: one for listening for new connection and another one for reading/writing from/two network threads, communicating with clients using some application-level protocol.

You will find some more detail in my past answer here:
Multple clients from same port Number[^].

Synchronization with other thread depends on your design. In particular, you may need to notify UI. You cannot call any UI methods from non-UI thread. Instead, you should use methods Invoke or BeginInvoke of System.Windows.Threading.Dispatcher or System.Windows.Forms.Control in all cases, including presenting exceptions. Please see detailed explanation of how it works and usage samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also links to my past answers on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA
 
Share this answer
 
Comments
BobJanova 14-Jun-11 12:17pm    
5+
Sergey Alexandrovich Kryukov 14-Jun-11 12:32pm    
Thank you, Bob.
--SA
<br />
As you familiar with backgroundworker, you know the all events that is provided by that component. One of them is DoWork event...<br />
whatever your code that you want to run in background (Asynchronously) should be in the method that is hooked to the DoWork event...<br />
<pre><br />
private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)<br />
{<br />
     bool flag = true;<br />
     while(!BackGroundWorker1.cancellationPending)<br />
     {<br />
         // from here call one function that check if connection is not alive then, it creates the connection..<br />
         // function that do another work....<br />
         // code block that set the flag(CancellationPending) as per your need<br />
         // this is infinate loop untill you set the flag true by calling a CancelAsync() method of BackGroundWorker1 control.<br />
     }<br />
    <br />
}<br />
</pre><br />
Thanks & Regards,<br />
Punit Parmar<br />
 
Share this answer
 
Comments
All Time Programming 17-Jun-11 3:40am    
Thanks Punit, In your while loop I have a problem. I can call a method (Connect()). If that fails - canot connect the I got to wait for 30 secs and then only try again. Over here what happens is as this is Asyn, Connect() has started its work, nect line i.e. check if its connected or not. As yet it is not connected, so it will wait for X secs and start Connect() again. I don't want this part to happen that's why I added the waiting in RunCompleted and then start background thread again which calls Connect(). Do you have a way to solve out this part ?
parmar_punit 17-Jun-11 6:48am    
thanks dear,
if you want to wait for x second then use System.Threading.Thread.Sleep(30000).
put that line in your code at where you did validation.
I mean, first check in connect() method whether connection is alive or not if it is not alive then make it sleep for x second and then it will automatically done.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900