-2

I want to terminate a function running in a thread

Thread t = new Thread(SomeFunction())
{
Background = true;
}

This someFunction() is running in background and from some other function(e.g. . CancelSomeFunction()) I have to cancel this thread t.

So I want to store something like threadId(t.ManagedThreadId()) in database and have to cancel the thread or want to use t.Abort().

I am using distributed system so I cant store thread instance in a variable to abort it in same class.

So is there any better way to get thread instance from thread id(stored in db) in C#?

Or any other way to cancel it, better if you explain with code snippet as I am new to c#.


Update

So If it can be done with cancellation token then is there any way to store token in db as there can be multiple task and we will be having multiple token for each task.

Suppose I am calling someFunction five times and I want to cancel what I clicked for the third time. Then I need to store something to cancel it(like token identifier from which I can get cancellationToken instance to call cancel() function. Is there any way to do so?

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
Aayush Grover
  • 53
  • 1
  • 4
  • This doesn't work at all. Aborting a thread is a terrible idea to begin with, the ManagedThreadId is unique only on the machine the thread runs and, especially on a distributed runtime like Service Fabric you don't own the threads in the first place – Panagiotis Kanavos Aug 29 '22 at 17:27
  • I suggest using `Task` instead of `Thread` and *cancellation* (`CancellationToken` and `CancellationTokenSource`) – Dmitry Bychenko Aug 29 '22 at 17:28
  • 1
    Even in desktop applications you should use cooperative cancellation using CancellationToken and CancellationTokenSource. Not nuke the runtime's threads. This can result in garbage or lost data, eg if the thread is aborted while writing to a file or database, or in the middle of an API call – Panagiotis Kanavos Aug 29 '22 at 17:28
  • Are you targeting the .NET Framework or the .NET Core / .NET 6? – Theodor Zoulias Aug 29 '22 at 17:28
  • `new Thread` is for Fire-and-forget threads where you don't want to interact with the thread after creating it. "Terminating" a thread counts as interacting with it. Even for such uses, it is very inefficient. Typically you should use [async/await](https://learn.microsoft.com/en-us/dotnet/csharp/async). This is more efficient and allows things like cancelling or getting results back from a thread. – Dour High Arch Aug 29 '22 at 17:30
  • I got it manipulating with threads wont help much...so, Can someone write one example to use task and cancellation token. as I want to run function in background. Is there something like in cancellationToken which i can store in db and get its instance to cancel it? – Aayush Grover Aug 29 '22 at 18:00
  • *so, Can someone write one example to use task and cancellation token* - @AayushGrover here is that requested example: https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation – Ibrennan208 Aug 29 '22 at 18:46
  • And if you need more: https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-cancel-a-task-and-its-children – Ibrennan208 Aug 29 '22 at 18:46
  • Can we store cancellation token in database if multiple tasks are running and each task is linked to id in a row. – Aayush Grover Aug 30 '22 at 09:40
  • @AayushGrover - No, you cannot. A cancellation token is an in memory object that safely communicates between threads. It is not actually a token that can be saved in the database. – Enigmativity Aug 30 '22 at 10:01
  • If you want to cancel a thread then the thread needs to cooperate. Otherwise, if you want to force it, then run your code in a separate process and kill the process. – Enigmativity Aug 30 '22 at 10:02
  • So we can store process id and cancel it?can you please give some reference on hot to create a process for SomeFunction – Aayush Grover Aug 30 '22 at 10:09

1 Answers1

1

If you want to cancel a thread then the thread needs to cooperate. Otherwise, if you want to force it, then run your code in a separate process and kill the process.

You can start a process and get its Id like this:

var p = Process.Start(new ProcessStartInfo() { FileName = "some_executable.exe" });
int id = p.Id;

Then you can save that to a database.

Later you can do this:

var p = Process.GetProcessById(id);
p.Kill();
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • The whole concept seems fragile. The operating system could crash after the app launched some processes, and then after restarting the PC the entries in the database would not correspond in processes launched by the app. So the app could kill accidentally some other unrelated process. – Theodor Zoulias Aug 30 '22 at 12:15
  • 1
    @TheodorZoulias - This is a good starting point. You could record other details like the EXE path or the start time to ensure you have the right process. – Enigmativity Aug 31 '22 at 00:14