Manually kill thread, created before - c#

I created a Thread, and want to kill him. I found my Thread in Process.GetCurrentProcess().Threads, but it has ProcessThread class, and can't be cast to Thread, so i can't kill him.
foreach (Thread thread in currentProcess.Threads)//throw error:unable to cast
{
if (thread.ManagedThreadId.Equals(processThreadId))
{
thread.Abort();
}
}

System.Diagnostics.ProcessThread isn't the same notion than System.Threading.Thread.
A quick solution is to save all task created in ConcurrentBag
int processThreadId = 0;
var threads = new ConcurrentDictionary<int,Thread>();
///...Some action
var newThread = new Thread(()=> {});
newThread.Start();
threads.TryAdd(newThread.ManagedThreadId,newThread);
///...Some action
Thread thread = null;
if(threads.TryRemove(processThreadId,out thread)){
thread.Abort();
}
It seems possible to translate ManagedThreadId into NativeThreadId
for more information Getting the thread ID from a thread

Related

Is it possible to await Thread in C#

I am in a situation where I have to spawn a new thread manually, so I am able to can call .SetApartmentState(ApartmentState.STA). This means (as far as I know) that I cannot use Task. But I would like to know when the thread was done running, something like the await which works with async. However, the best I can come up with is a loop, constantly checking Thread.IsAlive, like this:
var thread = new Thread(() =>
{
// my code here
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
while(thread.IsAlive)
{
// Wait 100 ms
Thread.Sleep(100);
}
This should work (as long as the thread don't end up stalling), but it seems kind of clumsy. Isn't there a more clever way to check when the thread is done (or dead)?
It is only to avoid blocking the GUI thread, so any minor performance hits are fine (like some hundred milliseconds).
Here is an extension method you could use to enable the awaiting of threads (inspired from this article: await anything).
public static TaskAwaiter GetAwaiter(this Thread thread)
{
return Task.Run(async () =>
{
while (thread.IsAlive)
{
await Task.Delay(100).ConfigureAwait(false);
}
}).GetAwaiter();
}
Usage example:
var thread = new Thread(() =>
{
Thread.Sleep(1000); // Simulate some background work
});
thread.IsBackground = true;
thread.Start();
await thread; // Wait asynchronously until the thread is completed
thread.Join(); // If you want to be extra sure that the thread has finished
Could you use the BackgroundWorker class? It has an event that reports when its finished.

What's the proper way to modify a string in a worker thread then read the result in the main thread?

So I was passing a an empty string from the main thread to a worker thread, then having the worker thread modify the string, and at a later time the main thread needed to be able to read the string. Of course, the string was being passed by value not by reference, so it couldn't be modified. I was able to get around this by passing a string array of size 1, but I would like to know if there's a cleaner way to solve this issue.
//in main thread
string errorMessage="";
System.Threading.Thread thread = new System.Threading.Thread(() => {
ProcessImport(path, errorMessage); });
thread.SetApartmentState(System.Threading.ApartmentState.STA);
thread.Start();
//in worker thread
if(errorDetected)
{
errorMesage= "some message";
}
//later in main thread
if(errorMessage!="")
{
CreateFeedbackMessageBox(erorrMesssage, 5000);
}

Creating a thread in C#

How would I go about in creating a thread in C#?
In java I would either implement the Runnable interface
class MyThread implements Runnable{
public void run(){
//metthod
}
and then
MyThread mt = new MyThread;
Thread tt = new Thread(mt);
tt.start()
or I could simply extend the Thread class
class MyThread extends Thread{
public void run(){
//method body
}
and then
MyThread mt = new MyThread
mt.start();
No, contrary to Java, in .NET you can't extend the Thread class because it's sealed.
So to execute a function in a new thread the most naive way is to manually spawn a new thread and pass it the function to be executed (as anonymous function in this case):
Thread thread = new Thread(() =>
{
// put the code here that you want to be executed in a new thread
});
thread.Start();
or if you don't want to use an anonymous delegate then define a method:
public void SomeMethod()
{
// put the code here that you want to be executed in a new thread
}
and then within the same class start a new thread passing the reference to this method:
Thread thread = new Thread(SomeMethod);
thread.Start();
and if you want to pass parameters to the method:
public void SomeMethod(object someParameter)
{
// put the code here that you want to be executed in a new thread
}
and then:
Thread thread = new Thread(SomeMethod);
thread.Start("this is some value");
That's the native way to execute tasks in background threads. To avoid paying the high price of creating new threads you could use one of the threads from the ThreadPool:
ThreadPool.QueueUserWorkItem(() =>
{
// put the code here that you want to be executed in a new thread
});
or using an asynchronous delegate execution:
Action someMethod = () =>
{
// put the code here that you want to be executed in a new thread
};
someMethod.BeginInvoke(ar =>
{
((Action)ar.AsyncState).EndInvoke(ar);
}, someMethod);
And yet another, and more modern way to execute such tasks is to use the TPL (starting from .NET 4.0):
Task.Factory.StartNew(() =>
{
// put the code here that you want to be executed in a new thread
});
So, yeah, as you can see, there are like gazzilions of techniques that could be used to run a bunch of code on a separate thread.

Share data between threads

I'm trying to implement an algorithm that should run in parallel using threads or tasks. The difficulty is that I want the threads/tasks to share their best results from time to time with all other threads.
The basic idea is this:
//Accessible from each thread
IProducerConsumerCollection<MyObject> _bestObjects;
//Executed in each thread
DoSomeWork(int n){
MyObject localObject;
for(var i = 0; i < n; i++){
//Do some calculations and store results in localObject
if((i/n)%0.5 == 0)
{
//store localObject in _bestObjects
//wait until each thread has stored its result in _bestObjects
//get the best result from _bestObjects and go on
}
}
}
How can this be achieved using System.Threading or System.Threading.Tasks and is it true that tasks should not be used for long running operations?
Update: Clarification
It's not my problem to have a thread safe collection but to make the threads stop, publish result, wait until all other threads have publihed their results to and then go on again. All threads will run simultaneously.
Cutting a long story short:
Whats better for long running operations? Task or Thread or anything else?
How to communicate between threads/taks to inform each of them about the state of all other assuming that the number of threads is set at runtime (depending on available cores).
Best Regards
Jay
Look at the dollowing example.
public class Worker
{
public SharedData state;
public void Work(SharedData someData)
{
this.state = someData;
while (true) ;
}
}
public class SharedData {
X myX;
public getX() { ... }
public setX(anX) { ... }
}
public class Sharing
{
public static void Main()
{
SharedData data = new SharedDate()
Worker work1 = new Worker(data);
Worker work2 = new Worker(data);
Thread thread = new Thread(new ThreadStart(work1.Work));
thread.start();
Thread thread2 = new Thread(new ThreadStart(work2.Work));
thread2.start();
}
}
bomslang's response is not accurate. Cannot instantiate a new thread with ThreadStart, passing in Work method which requires a parameter to be passed in the above example. ParameterizedThreadStart would be more suitable. The sample code for the Main method would look more like this:
public class Sharing
{
public static void Main()
{
SharedData data = new SharedDate()
Worker work1 = new Worker(data);
Worker work2 = new Worker(data);
Thread thread = new Thread(new ParameterizedThreadStart(work1.Work));
thread.start(someData);
Thread thread2 = new Thread(new ParameterizedThreadStart(work2.Work));
thread2.start(someData);
}
}
Note that 'work' is being passed into the ParameterizedThreadStart as the method for the new thread to execute, and the data required to pass in to the 'work' method is being passed in the call to start. The data must be passed as an object, so the work method will need to cast it back to the appropriate datatype as well. Lastly, there is also another approach to passing in data to a new thread via the use of anonymous methods.

Stop thread immediately

I have a long running task in a thread. I
Thread a = new Thread(new ThreadStart()({ delegate()
{
Catalog.Generate(); //long running task
}));
a.Start();
Thread b = new Thread(new ThreadStart()({ delegate()
{
if( File.Exists(stopFile) )
{
a.Abort();
}
}));
b.Start();
This stops Thread A when the stop file is created BUT the catalog.generate method still keeps running? How do I end it?
The problem is your thread b starts working and does the check and immediately exits.
You have to add some sort of loop for the thread b to keep running (this is example code not best practice):
Thread b = new Thread(new ThreadStart()({ delegate()
{
int t=0;
while(i<100)
{
if( File.Exists(stopFile) )
{
a.Abort();
}
else
{
i++;
Thread.Sleep(500);
}
}
}));
"Raises a ThreadAbortException in the thread on which it is invoked, to begin the process of terminating the thread. Calling this method usually terminates the thread."
The abort method sends an indicator that the thread should close. It is dependent on the thread processing as to how it handles this, and when it responds. I would suggest that the Catalog.Generate is probably refusing to respond.

Categories