Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set a timeout for a dynamically loaded method

Tags:

c#

dll

Description: I am using Type.InvokeMember to call a method from a dynamically loaded library. Sometimes, this method hangs and does not release its resources. In addition, the method does not take a timeout as a parameter.

How can I set a timeout for this method, STOP the method from running in the background, and move on to the next step?

Any help would be appreciated!

like image 681
Raed M Avatar asked Jul 13 '26 14:07

Raed M


1 Answers

Props to @lightbricko as his methodology will give you the abort functionality you need.

As far as a timeout is concerned, it may be easier to provide a wrapper class for monitoring the time and invoking the solution on a separate thread.


Your question fails to mention if there is a return value, or a requirement for synchronicity. I'll present a solution with increasing levels of complexity depending on the requirements. Please respond to this thread if you need me to flesh out the more complex solutions.


Not in my IDE, so I whipped this up in Notepad. Its a bit dirty but should give you a skeleton to work from.

You can pass in the necessary parameters for invoking the method. For bonus points check out Action and Function delegates! :)

public class TimedRemoteInvocation
{
    Timer myTimer;
    Thread myThread;

    public static RemoteInvocationTimer Invoke(..., int timeout)
    {
        return new RemoteInvocationTimer().InvokeMember(...)

    }

    private RemoteInvocationTimer InvokeMember( ..., int timeout )
    {
        myTimer = new Timer();
        myTimer.Elapsed += new ElapsedEventHandler( TimeOutOccurred );
        myTimer.Interval = timeout; //ex: 200ms
        myThread = new Thread(
            new ThreadStart(theTypeObj.InvokeMember(...));

        myTimer.Start();
        mythread.start();
        return this;
    }

    public void ElapsedEventHandler( Object sender, ElapsedEventArgs e )
    {
        myThread.Abort()
    }

}

If you need this to appear synchronous to the caller (that is, the caller needs to wait for completion) let me know and I'll update the code. The idea would be for the caller to wait on a lock mutex. That lock would be grabbed first by the TimedRemoteInvocation class, and released when the operation completes. Again I can provide more info if you need it.

TimedRemoteInvocation caller = TimedRemoteInvocation.Invoke(...)
lock(caller.sharedLock) {}

The final variation expects a result from the invoked method. This can be easily captured but returning that value to the caller would either require

  1. The caller to handle an event that declares a result

  2. Should synchronicity be required, the result can be stored in a property of the TimedRemoteInvocation class (again the use of a mutex lock would be required).

    TimedRemoteInvocation caller = TimedRemoteInvocation.Invoke(...)
    res = caller.Result //The result property will grab/wait on the mutex and halt the caller.

There's a lot to unpack here and I know I'm glossing over things, so let me know if you need me to add to anything.

like image 119
JFish222 Avatar answered Jul 16 '26 05:07

JFish222



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!