0

I have a "Module" abstract base class which users inherit from to create dll's for a particular program. This base class exposes an abstract method "ProcessData" which does some processing on data and returns the processed data. The main program iterates over all the included dll's and calls everyone's "ProcessData" function. Kind of like this:

foreach (Module module in allModules)
{
   Data newData = module.ProcessData(oldData);
   //Do stuff with newData
}

There's a general "contract" that dll creators should abide by, which is that no file IO, web access, etc. should be performed in "ProcessData". However, some of these user modules have bugs which occur every once in a while in which they enter an infinite loop (or so I assume).

If I don't know what the heck these users are doing in their functions, is there still a way to halt their function execution if it's taking too long? I'd like my program to be robust enough to halt a module's execution if it detects that it's taking far too long, since right now the process thread just gets stuck forever. I've heard that starting a thread and then attempting "Abort" doesn't always work due to exception handling (among other things), but if I'm not in charge of the function, there must be some way for me to force it to stop. Hopefully....

Carlos Sanchez
  • 986
  • 1
  • 10
  • 17
  • 1
    Run it in a separate process, use one of the .NET process interop mechanisms to talk to it. You can shoot the process in the head with Process.Kill(), the OS cleans up. – Hans Passant Jan 31 '15 at 23:50
  • 1
    @HansPassant seeing that ProcessData() is just a function call, how about running it in a Task with a timeout? http://stackoverflow.com/questions/4238345/asynchronously-wait-for-taskt-to-complete-with-timeout – supertopi Jan 31 '15 at 23:52
  • @supertopi I thought that await/async and all that only work on functions which allow execution to return to the caller due to a potential block (like file IO). If the user's function just enters an infinite loop, would running a task with a timeout still work? – Carlos Sanchez Jan 31 '15 at 23:54
  • @limitlessinfinity after reading 5min about it, it would not work. The Task at hand should be able to support cancellation with a CancellationToken. This is not the case with your ProcessData() – supertopi Feb 01 '15 at 00:09

1 Answers1

1

You have several options ordered by reliability and robustness in that order.

Recommended way is you could create separate process and execute the hostile code there. Doing so will give you a chance to kill the process anytime you want.

You could create separate AppDomain and run the code in that new AppDomain, and you can choose to unload the AppDomain anytime you want. This is not robust as first option. But there is one.

You might be tempted to just call Thread.Abort but don't do that. It isn't doing what you expect it to do.

Related reading: Careful with that axe, part one: Should I specify a timeout?

Community
  • 1
  • 1
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • Wouldn't the process memory need to be copied in order to start a separate process but with the same data? What if my process currently has a UI that I don't want to bring over to the new process? Or does C# handle the creation of processes differently than, say, "fork()"? – Carlos Sanchez Feb 01 '15 at 00:06
  • 1
    Yes new process will have a different memory you can't share it. You need some kind of IPC mechanism to communicate between them. No you don't need to share a UI, you can create new console application, you could hide the console also from being shown. No C# process creation isn't any different what how you do with WIn32 – Sriram Sakthivel Feb 01 '15 at 00:20
  • 1
    @limit The whole reason process.kill is safe while thread.abort is not, is because they don't share memory and resources! That's an inherent limitation that you can't work around (sandboxing theoretically, but the account of bugs in every existing implementation of it shows how that's a pipe dream) – Voo Feb 01 '15 at 17:12