1

I'm designing a plugin system for my app.

there is a "Start" button in UI. When user clicks on it, app should call a method in plugin dll asynchronously and change "Start" to "Stop". That method could include almost anything as it is for plugin. When user clicks "Stop", that asynchronous method should be terminated immediately.

I wanted to use Thread.Abort(); but everyone recommends not to use it. If I use CancellationTokenSource, I have to add cancellation handling to all plugins and I prefer not to do this.

I need something like a force shutdown, unplug or destroy (if needed!) for a PC. The only important thing for me is immediate stop. No cleanup or things like this are needed as my app unloads the plugin after using it and plugins have nothing to do with main app codes.

Isn't there anyway to start a method asynchronously and have full control on it? Is it OK to use Thread.Abort(); in this situation (if I guarantee the dll won't catch thread abort exception)?

EDIT: Is there any way to actively monitor cancellation token in plugin dll (class) asynchronously while running method and kill method when requested?

EDIT2: I think it is not a good idea but what about creating a new process and use Process.kill()?

AmirSina Mashayekh
  • 498
  • 1
  • 5
  • 21
  • Do no mix tasks and threads – Pavel Anikhouski May 22 '20 at 06:57
  • By task, I didn't mean Task; I mean something to run; like methods. – AmirSina Mashayekh May 22 '20 at 06:58
  • 2
    Please share example of your code so far, it helps other to understand what do you want to achieve. You can also have a look at [Cancellation in Managed Threads](https://learn.microsoft.com/en-us/dotnet/standard/threading/cancellation-in-managed-threads) article – Pavel Anikhouski May 22 '20 at 07:00
  • Can you show the code of the asynchronous method that you would like to abort immediately? – Theodor Zoulias May 22 '20 at 07:24
  • @PavelAnikhouski I can't because that code could be almost anything! remember: "Plugin System" – AmirSina Mashayekh May 22 '20 at 07:55
  • 1
    The problem with `Thread.Abort` is exactly with the situation you're describing - the code could be doing *anything*. Say it's in the middle of changing some global state and other code/processes is protected from seeing the effects mid-change through the use of a mutex. Well, congratulations, the mutex gets abandoned *and* the state is corrupted. – Damien_The_Unbeliever May 22 '20 at 08:37
  • @Damien_The_Unbeliever I don't know what do you mean by _global state_ but as I said, that method has nothing to do with main app. It communicates with serial port, calculates, does some other favorite things not related to main app, sets a property inside plugin class which main app **may** use it, and finish. And as I said, no cleanup is needed as the app will unload the plugin. – AmirSina Mashayekh May 22 '20 at 08:45

1 Answers1

4

No, I'm afraid you have to use an extra parameter for the cancellation token.

Avoid working with threads as they are pretty low-level and try to use the utilities and abstractions of Tasks, which hide much of the hassle.

Edit: You mention in your answer and in your comments that you want to cancel an asynchronous method, but you also mention this not to be a Task. This baffles me. Let's say you have a class where you handle the Start / Stop code.

- Start

When you want to start the asynchronous processing of your plugin, you will have to create a new CancellationTokenSource(), and hold it as a private variable in the class that controls the Start/Stop.

Let's say now that you now have a method that you want to run asynchronously, and it has the signature: public Task Run(string anyArgument).

You should also add another argument, so it becomes: public Task Run(string anyArgument, CancellationToken token) Most libraries that expose asynchronous methods also accept an optional parameter for the CancellationToken. The logic behind this is that when (from any place) you want the process cancelled, you request the token to stop, and in its turn it will stop any asynchronous operation, if it's checked.

Having said that, let's go to...

- Stop

If you want to stop the operation, you will simply use the CancellationTokenSource that you initialized in the Start method, and will call cts.Cancel()

More information about handling of CancellationTokens you can find in the documentation or in this SO question

Also check:

Sotiris Panopoulos
  • 1,523
  • 1
  • 13
  • 18
  • Sorry but as I'm a beginner, I need more detailed answer! – AmirSina Mashayekh May 22 '20 at 06:46
  • I have edited my answer with some more details, providing also some links to understand the concept a bit better. Without a sample of your existing code though, I could only make my explanations at a high level and not dive deep into a solution that will fit your exact needs. – Sotiris Panopoulos May 22 '20 at 12:33
  • Thanks but I knew these! I prefer not to include cancellation related things is plugin main method. What about the question I added in edit? – AmirSina Mashayekh May 22 '20 at 12:41
  • Well, I used CancellationTokenSource but also used Thread.Abort() for when CancellationTokenSource isn't working. (emergency situations!) – AmirSina Mashayekh May 24 '20 at 20:36