Delegates and exceptions

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Pietje de kort

    Delegates and exceptions

    Hello all,

    I want to implement Timeout behaviour in a class of mine. When a
    method is called it should timeout after a few seconds. To do this
    I've built a
    System.Threadin g.Timer that calls a delegate method after x milli's,
    the called
    delegate throws an exception indicating timeout.
    The big problem is my code will not catch the thrown exception because
    it
    is generated outside of normal program control. Is there any way to
    catch the
    exception thrown (other than hooking the UncaughtExcepti on event)?

    Best regards Wouter

    using System.Threadin g;

    public class Test
    {
    public Test(){};

    public DoTimeoutAction ()
    {
    Timer timer = new Timer(new TimerCallback(T imedout),null,
    1000,Timeout.In finite);
    Console.WriteLi ne("Doing something");
    Thread.Sleep(50 00); // will cause timeout to occur
    Console.WriteLi ne("Done doing something");
    timer.Dispose() ; // stop timer
    }

    private void Timedout(object state)
    {
    throw new ApplicationExce ption("Timeout occured.");
    }

    static void Main()
    {
    Test t = new Test();
    try
    {
    t.DoTimeoutActi on();
    }catch(Applicat ionException e)
    {
    Console.WriteLi ne(e.Message);
    }
    Console.WriteLi ne("Done!");
    Console.ReadLin e();
    }
    }
  • Fred Mellender

    #2
    Re: Delegates and exceptions

    I believe the problem is that the timer and its timeout function run on a
    separate thread from the one that started the timer up (see the help page on
    Threading.Timer ). Because there is no way to specify an exception handler
    on that (system created) thread, you cannot catch an exception thrown in the
    timeout thread. If possible you might try to place your exception-catch
    logic in the timeout function itself.

    Perhaps another way:

    Have a separate thread ("controller ") start the "calculator " on its on
    thread. Then in controller, do a
    calculator.Join (TimeSpan). In statements following the Join, the
    controller can check to see that the calculator thread has completed
    normally (via Thread.IsAlive, or a bool set by calculator itself). If not,
    controller can put out a message, kill calculator, or do another join to
    give it more time.


    "Pietje de kort" <woutervu@hotma il.com> wrote in message
    news:e09cc77a.0 310140314.9cd7c 4a@posting.goog le.com...[color=blue]
    > Hello all,
    >
    > I want to implement Timeout behaviour in a class of mine. When a
    > method is called it should timeout after a few seconds. To do this
    > I've built a
    > System.Threadin g.Timer that calls a delegate method after x milli's,
    > the called
    > delegate throws an exception indicating timeout.
    > The big problem is my code will not catch the thrown exception because
    > it
    > is generated outside of normal program control. Is there any way to
    > catch the
    > exception thrown (other than hooking the UncaughtExcepti on event)?
    >
    > Best regards Wouter
    >
    > using System.Threadin g;
    >
    > public class Test
    > {
    > public Test(){};
    >
    > public DoTimeoutAction ()
    > {
    > Timer timer = new Timer(new TimerCallback(T imedout),null,
    > 1000,Timeout.In finite);
    > Console.WriteLi ne("Doing something");
    > Thread.Sleep(50 00); // will cause timeout to occur
    > Console.WriteLi ne("Done doing something");
    > timer.Dispose() ; // stop timer
    > }
    >
    > private void Timedout(object state)
    > {
    > throw new ApplicationExce ption("Timeout occured.");
    > }
    >
    > static void Main()
    > {
    > Test t = new Test();
    > try
    > {
    > t.DoTimeoutActi on();
    > }catch(Applicat ionException e)
    > {
    > Console.WriteLi ne(e.Message);
    > }
    > Console.WriteLi ne("Done!");
    > Console.ReadLin e();
    > }
    > }[/color]


    Comment

    • Nicholas Paldino [.NET/C# MVP]

      #3
      Re: Delegates and exceptions

      Pietje,

      You have to go about this the opposite way actually. The first thing
      you need to do is indicate somewhere if the operation completed or not. You
      can use a boolean flag for this. Once you have that, you should expose it
      as a property (public or private, it is up to you). You need to place a
      lock section around the access of this variable.

      After that, in your method, you call your operation asynchronously in
      another thread (through the thread pool or a separate thread). In the code
      that is performing the work, when complete, set the flag to true.

      In the code that calls out to the other thread, after the asynchronous
      call is made, you can call the static Sleep method to sleep for the amount
      of time you want to wait. If the flag is not set when execution resumes,
      you can throw your exception.

      Of course, this means that if your operation completes, you have to wait
      the same amount of time. In order to get around this, replace the boolean
      flag with a WaitHandle, such as an event. In your operation, instead of
      setting the boolean flag, set the Event. Also, instead of having the thread
      put to sleep, you wait on the handle. Before you wait on the handle, you
      set your timer to call back a method and set the event when it calls back.
      The flag comes in useful here in the timer method, where you will set it to
      true. This way, when the call to WaitOne on the Event is complete, you will
      know if it timed out or not.

      Hope this helps.


      "Pietje de kort" <woutervu@hotma il.com> wrote in message
      news:e09cc77a.0 310140314.9cd7c 4a@posting.goog le.com...[color=blue]
      > Hello all,
      >
      > I want to implement Timeout behaviour in a class of mine. When a
      > method is called it should timeout after a few seconds. To do this
      > I've built a
      > System.Threadin g.Timer that calls a delegate method after x milli's,
      > the called
      > delegate throws an exception indicating timeout.
      > The big problem is my code will not catch the thrown exception because
      > it
      > is generated outside of normal program control. Is there any way to
      > catch the
      > exception thrown (other than hooking the UncaughtExcepti on event)?
      >
      > Best regards Wouter
      >
      > using System.Threadin g;
      >
      > public class Test
      > {
      > public Test(){};
      >
      > public DoTimeoutAction ()
      > {
      > Timer timer = new Timer(new TimerCallback(T imedout),null,
      > 1000,Timeout.In finite);
      > Console.WriteLi ne("Doing something");
      > Thread.Sleep(50 00); // will cause timeout to occur
      > Console.WriteLi ne("Done doing something");
      > timer.Dispose() ; // stop timer
      > }
      >
      > private void Timedout(object state)
      > {
      > throw new ApplicationExce ption("Timeout occured.");
      > }
      >
      > static void Main()
      > {
      > Test t = new Test();
      > try
      > {
      > t.DoTimeoutActi on();
      > }catch(Applicat ionException e)
      > {
      > Console.WriteLi ne(e.Message);
      > }
      > Console.WriteLi ne("Done!");
      > Console.ReadLin e();
      > }
      > }[/color]


      Comment

      • Pietje de kort

        #4
        Re: Delegates and exceptions

        Hi Nicholas,

        that's exactly what I found on some MSDN site!
        Here's my example code. The actual work is done
        in the DoAction method which signals it's done.

        Best regards, Wouter van Vugt (not pietje ;) )

        using System;
        using System.Collecti ons;

        using System.IO;
        using System.Threadin g;

        namespace TestApp
        {
        public class TimeoutTest
        {
        private AutoResetEvent autoEvent;
        private int timeout;

        public TimeoutTest(int timeout)
        {
        this.timeout = timeout;
        this.autoEvent = new AutoResetEvent( false);
        }

        public void DoTimeoutAction ()
        {
        Console.WriteLi ne("Delegating request to work item.");
        ThreadPool.Queu eUserWorkItem(n ew WaitCallback(Do Action),null);
        Console.WriteLi ne("Waiting for work item to complete.");
        int index = WaitHandle.Wait Any(new AutoResetEvent[]{autoEvent},tim eout,false);

        if (index == WaitHandle.Wait Timeout)
        throw new ApplicationExce ption("Timedout ");
        Console.WriteLi ne("Work item completed!");
        }

        private void DoAction(object state)
        {
        Console.WriteLi ne("DL Doing Work...");
        Thread.Sleep(50 00);
        Console.WriteLi ne("DL Done doing work.");
        autoEvent.Set() ;
        }

        static void Main()
        {
        try
        {
        TimeoutTest t = new TimeoutTest(100 00);
        t.DoTimeoutActi on();
        }
        catch(Applicati onException e)
        {
        Console.WriteLi ne(e.Message);
        }
        Console.ReadLin e();
        }
        }
        }



        "Nicholas Paldino [.NET/C# MVP]" <mvp@spam.guard .caspershouse.c om> wrote in message news:<usp7XFlkD HA.2456@TK2MSFT NGP09.phx.gbl>. ..[color=blue]
        > Pietje,
        >
        > You have to go about this the opposite way actually. The first thing
        > you need to do is indicate somewhere if the operation completed or not. You
        > can use a boolean flag for this. Once you have that, you should expose it
        > as a property (public or private, it is up to you). You need to place a
        > lock section around the access of this variable.
        >
        > After that, in your method, you call your operation asynchronously in
        > another thread (through the thread pool or a separate thread). In the code
        > that is performing the work, when complete, set the flag to true.
        >
        > In the code that calls out to the other thread, after the asynchronous
        > call is made, you can call the static Sleep method to sleep for the amount
        > of time you want to wait. If the flag is not set when execution resumes,
        > you can throw your exception.
        >
        > Of course, this means that if your operation completes, you have to wait
        > the same amount of time. In order to get around this, replace the boolean
        > flag with a WaitHandle, such as an event. In your operation, instead of
        > setting the boolean flag, set the Event. Also, instead of having the thread
        > put to sleep, you wait on the handle. Before you wait on the handle, you
        > set your timer to call back a method and set the event when it calls back.
        > The flag comes in useful here in the timer method, where you will set it to
        > true. This way, when the call to WaitOne on the Event is complete, you will
        > know if it timed out or not.
        >
        > Hope this helps.
        >
        >
        > "Pietje de kort" <woutervu@hotma il.com> wrote in message
        > news:e09cc77a.0 310140314.9cd7c 4a@posting.goog le.com...[color=green]
        > > Hello all,
        > >
        > > I want to implement Timeout behaviour in a class of mine. When a
        > > method is called it should timeout after a few seconds. To do this
        > > I've built a
        > > System.Threadin g.Timer that calls a delegate method after x milli's,
        > > the called
        > > delegate throws an exception indicating timeout.
        > > The big problem is my code will not catch the thrown exception because
        > > it
        > > is generated outside of normal program control. Is there any way to
        > > catch the
        > > exception thrown (other than hooking the UncaughtExcepti on event)?
        > >
        > > Best regards Wouter
        > >
        > > using System.Threadin g;
        > >
        > > public class Test
        > > {
        > > public Test(){};
        > >
        > > public DoTimeoutAction ()
        > > {
        > > Timer timer = new Timer(new TimerCallback(T imedout),null,
        > > 1000,Timeout.In finite);
        > > Console.WriteLi ne("Doing something");
        > > Thread.Sleep(50 00); // will cause timeout to occur
        > > Console.WriteLi ne("Done doing something");
        > > timer.Dispose() ; // stop timer
        > > }
        > >
        > > private void Timedout(object state)
        > > {
        > > throw new ApplicationExce ption("Timeout occured.");
        > > }
        > >
        > > static void Main()
        > > {
        > > Test t = new Test();
        > > try
        > > {
        > > t.DoTimeoutActi on();
        > > }catch(Applicat ionException e)
        > > {
        > > Console.WriteLi ne(e.Message);
        > > }
        > > Console.WriteLi ne("Done!");
        > > Console.ReadLin e();
        > > }
        > > }[/color][/color]

        Comment

        Working...