3

I want to call a method which returns a value every few seconds. I have tried using a Timer with elapsedEventandler, but the return type of the method is void in this case. I have used the TimerTask class to perform the same task in Java.

I want it to be in .NET 2.0 as I'm using Visual Studio 2005.

Below is the program I'm having trouble with. I tried to use an anonymous method, but the value of response in this case does not exist outside the anonymous method:

public static string Run(string address)
{                     
    string response = "A";
    Timer t = new Timer();
    t.Elapsed += delegate 
    {                         
        response = callURL(address);
        console.writeln(response);
        // The actual response value is printed here                
    };          
    t.Interval = 3000;
    t.Start();                      
    Console.WriteLine("response string is " + response);
    // response string is A

    return response;
}

public static string callURL(string address)
{
    className sig = new ClassName(); 
    String responseBody = sig.getURL(address);

    return responseBody;
}

How do I get the value of response in the Run method and send it to the caller of the Run method?

BSMP
  • 4,596
  • 8
  • 33
  • 44
Bharath
  • 1,787
  • 1
  • 20
  • 37

2 Answers2

9

You could have your caller give the class with the timer a callback delegate to pass back the value.

public class YourClass
{
    public static void Run(string address, Action<string> callback)
    {                     
        Timer t = new Timer();
        t.Elapsed += delegate {                         
            var response = callURL(address);

            callback(response);
        };          
        t.Interval = 3000;
        t.Start();
    }
}

public class OtherClass
{
    public void ProcessResponse(string response)
    {
         // do whatever you want here to handle the response...
         // you can write it out, store in a queue, put in a member, etc.
    }

    public void StartItUp()
    {
         YourClass.Run("http://wwww.somewhere.net", ProcessResponse);
    }
}

UPDATE: If you want the caller (OtherClass) to be able to cancel the timer, you could simply change from an Action<string> to a Func<string, bool> and have the caller (OtherClass) return a bool on whether to stop the timer or not...

public class YourClass
{
    public static void Run(string address, Func<string, bool> callback)
    {                     
        Timer t = new Timer();
        t.Elapsed += delegate {                         
            var response = callURL(address);

            // if callback returns false, cancel timer
            if(!callback(response))
            {
                t.Stop();
            }
        };          
        t.Interval = 3000;
        t.Start();
    }
}

public class OtherClass
{
    public bool ProcessResponse(string response)
    {
         // do whatever you want here to handle the response...
         // you can write it out, store in a queue, put in a member, etc.
         // check result to see if it's a certain value...
         // if it should keep going, return true, otherwise return false
    }

    public void StartItUp()
    {
         YourClass.Run("http://wwww.somewhere.net", ProcessResponse);
    }
}
Lauren Rutledge
  • 1,195
  • 5
  • 18
  • 27
James Michael Hare
  • 37,767
  • 9
  • 73
  • 83
  • wow james michael hare.. that was quick and awesome. thank you. :) – Bharath May 16 '12 at 20:37
  • Anytime! You'll still have to write the code to handle your responses, of course, but that at least gives you the framework... – James Michael Hare May 16 '12 at 20:38
  • i was so lost from yesterday. The rest should not be a problem i guess. this was the main thing. i was trying to convert code from java to c#. and i was so lost here. – Bharath May 16 '12 at 20:39
  • one quick question. how do i stop the timer inside the anonymous method? – Bharath May 16 '12 at 20:46
  • @Bharath: when do you want to stop it? Do you want to stop it after the first item? After you retrieve a particular result? After X minutes? – James Michael Hare May 16 '12 at 20:48
  • yes.. i have to stop it after i get a particular result. also, is it possible to stop it after X minutes. ex: when i do not get any response? – Bharath May 16 '12 at 20:52
  • Thank you so much James. you made my day a lot shorter today. – Bharath May 16 '12 at 21:06
0

Create a Thread and make the thread call the method you want and give a sleep time to the thread for 5 seconds:

Thread loopThread = new Thread(new ThreadStart(this.MainLoop));
loopThread.Start();

private void MainLoop()
{
     while(true)
     {
         // Do stuff
         Thread.Sleep(5000);
     }
}
Lauren Rutledge
  • 1,195
  • 5
  • 18
  • 27
tmjam
  • 1,029
  • 2
  • 12
  • 25
  • is it not possible to do it using Timers? i want the method called by the thread, in this case MainLoop to return a value. – Bharath May 16 '12 at 20:20
  • 2
    Sorry, I'm an insomniac, I hate Sleep() :-) – James Michael Hare May 16 '12 at 20:21
  • using Threads is a cleaner way, as you will not halt your whole system with timers ? – tmjam May 16 '12 at 20:25
  • @James: Thank you sir, after doing a bit of research and this post http://stackoverflow.com/questions/1091710/c-sharp-timer-or-thread-sleep. I agree Timmers are useful in some places as in this case – tmjam May 17 '12 at 02:51