0

I have a case where I am using multiple threads to query from a web service. Once in a time, I have to authenticate myself to the web server because session expires after this time. I do the authorization like:

static void threadCall(){
    try{
        ws.query();
    }
    catch(AuthenticationFailException ex){
        AuthAgain();
        threadCall();
        return;
    }
}

The problem is, authentication fails for multiple threads and multiple threads want to authenticate at the same time. This slows the process so I want to authenticate for 1 thread only and want other threads to wait until authentication is done. How can I achieve this.

Gokhan Kurt
  • 8,239
  • 1
  • 27
  • 51
  • Search for [MethodImpl(MethodImplOptions.Synchronized)] or http://stackoverflow.com/questions/391913/re-entrant-locks-in-c-sharp – Ako Mar 02 '15 at 08:04
  • Actually, these are not what I am looking for. They are for threads to wait other threads to finish their job. So every thread will do that job once the other thread finishes. What I want is, the job must be done once. – Gokhan Kurt Mar 02 '15 at 08:06
  • Cheap solution: Between all threads accessible bool that is set to true and inside of your other threads you do a while loop that does a Thread.Sleep with a reasonable time so that you do not use more capacity than you need to and then when your one thread is done authenticating you set the bool to false. Another thing that might be useful to get a cleaner solution to your problem is looking into the Task.Wait()-method https://msdn.microsoft.com/de-de/library/dd537610%28v=vs.110%29.aspx – Paul Weiland Mar 02 '15 at 08:16

1 Answers1

0

I would do something like this.

bool authenticated = false;
object lockObject = new object();

static void threadCall(){
    verifyAuthentication();
    try{
        ws.query();
    }
    catch(AuthenticationFailException ex){
        authenticated = false;
        threadCall();
        return;
    }
}

static void verifyAuthentication()
{
    if (!authenticated)
    {
        lock (lockObject)
        {
            if (!authenticated)
            {
                AuthAgain();
                authenticated = true;
            }
        }
    }
}
Ako
  • 1,193
  • 14
  • 22
  • Ok, remember that you need to cope with authentication problems. In this example it will hit stackoverflow because of recursive call of threadCall. – Ako Mar 02 '15 at 08:52
  • This decreases the number of authentications done, but it is not perfect. After a thread finishes authentication, if another thread is in the line after the catch, it can set authenticated to false. – Gokhan Kurt Mar 02 '15 at 09:26
  • Yes, the variable is set to false. But it should not re-authenticate because the thread will wait on the lock and inside the lock, the status is checked again. – Ako Mar 02 '15 at 10:21