1

Our program is executing unknown methods from a DLL. Sometimes those methods won't handle timeouts and will never return a value.

Thus, our Methodinfo.invoke(...) will be stuck on this line forever.

Is there any decent way to abort our method? I understand that i should probably run this method asyncronious which is no problem.

as requested here is some little example for visualisation:

 public string startTheDLLMethod(int timeout)
    {
        var methodinfo = "...";

        return methodGettingStuck(methodinfo); //todo, abort this after timeout
    }

    public string methodGettingStuck(methodinfo)
    {
        var1 = "";
        var2 = "";

        methodinfo.Invoke(var1, var2); //Stuck.
    }
humudu
  • 699
  • 1
  • 7
  • 13
  • `ThreadAbortException`? Please provide a [mcve]. – dymanoid Sep 27 '17 at 10:36
  • Read more about [`CancellationTokenSource`](https://msdn.microsoft.com/en-us/library/system.threading.cancellationtokensource(v=vs.110).aspx). – Shreevardhan Sep 27 '17 at 10:42
  • Are you claiming that CancellationTokenSource is able to stop the method while it's stuck on 1 line – humudu Sep 27 '17 at 10:46
  • 2
    Does the DLL allocate something difficult? I would not suggest working with Thread.Abort and ThreadAbortException when the DLL allocates FileHandles or something similar. – quadroid Sep 27 '17 at 10:46
  • I cannot know what future DLL's from different companies will do, so maybe – humudu Sep 27 '17 at 10:51

1 Answers1

3

As suggested in the comment i would try to not work with ThreadAbortException if something like a file handle is allocated within the dll.

But here you go:

    public void BlockingCallWithTimeout()
    {
        Semaphore waitHandle = new Semaphore(0,1);
        Thread thread = new Thread(this.Wrapper);
        Timer timer = new Timer(state =>
        {
            thread.Abort();
            waitHandle.Release();
        },null,5000,0);

        thread.Start(waitHandle);

        waitHandle.WaitOne(); //wait until completion or until timeout
        timer.Dispose();
    }

    public void Wrapper(object state)
    {
        Semaphore semaphore = (Semaphore)state;

        //Call DLL Method

        semaphore.Release();
    }

You need to handle the ThreadAbortException somewhere in the code (did not try it). This code is just an example! you need to take care of the case where timeout and success occur at the same time. So the Timer is not disposed the moment it is executing - and there may be more race conditions to take care of.

quadroid
  • 8,444
  • 6
  • 49
  • 82
  • It gave a few difficulties since the method needed to return a string, and accept several objects and variables as parameters, but i worked around that. The solution works, aborting the threads might cause an issue if they are in middle of something, but atleast I can now tell the user that it's not my program, but the DLL that's bad, which was a goal. Thanks – humudu Sep 27 '17 at 13:25
  • Update: If the method is using a resource like a COM port, and you abort the thread, it would result in a "Safe handle has been closed" error and program crash. But i managed to work around that as well by having the executing thread in a different appdomain. https://stackoverflow.com/questions/46562227/safe-handle-has-been-closed-thread-abort-can-program-crash-be-avoided – humudu Oct 06 '17 at 13:01