How to kill Thread in C# instantly - c#

I'm using thread to download something from internet.
I don't have any loop inside my thread method. I'm using StreamReader.ReadToEnd() method, so
when my thread is downloading something large I want to stop this thread. Preferably without Thread.Abort() method.
Is it possible to give to GC thread to clean, or to finish this?

Don't do a ReadToEnd, instead create a loop and read X chars at a time (or read a line at a time with ReadLine). Within the loop check whether an AutoResetEvent is set (using .WaitOne(0)), if it is then exit the loop.
Set the reset event (using Set) in your other thread when you want to stop the download.

You could use the BaseStream BeginRead() async method. You're better off using this rather than spawning your own dedicated thread (which consumes 1MB of committed memory). The async methods are more efficient as they use I/O completion ports.
new StreamReader(aStream).BaseStream.BeginRead()
Here's some more info http://msdn.microsoft.com/en-us/library/system.io.stream.beginread.aspx
A related thread on stopping an async read.
Stop Stream.BeginRead()

What George Duckett says but you could use .Net 4 Task class to start the thread/asynchronous task and pass in a CancellationToken and in the loop check if IsCancellationRequested = true

Related

C# finding managed thread

I'm using the System.Threading.Thread object to create a background-working method. The method loads data which can also be used by the user in the current time (must be read from the same source). That's why I'd like to find the created Thread and pause it for the time of current data-loading.
Here comes the problem... How to find the Thread?
I've already read about System.Diagnostics.Process attempt, but it contains data only about the OS-Threads.
Also I need to say that the method starting the Thread is static and it's possible but really unwanted to create an object to track the thread. I'm just creating new object and starting it...
(new Thread(new ThreadStart(...))).Start();
I've looked through many topic but I found no following question:
IF IT'S IMPOSSIBLE, THAN FROM WHERE THE VISUAL STUDIO -> THREAD WINDOW TAKES INFORMATION!?
Thanks in advance for any help :)
If pausing the "reading" thread is truly required, you can have it wait for a signal using the EventWaitHandle class, set as Manual or Automatic reset depending on your use case, starting unset. The background thread, when it has finished writing to whatever the shared variable location is, can set the signal on the wait handle to release the "reading" thread that was stuck waiting.
If your "reading" thread only needs to pause sometimes, you can use the same wait handle approach, except have it start as "set" in Manual Reset mode while your "reading" thread checks it whenever appropriate. The "reading" thread will skip over waiting for the signal (because it's already set)!
Once your "writing" thread needs to make a change, it would reset the wait handle, causing your "reading" thread to pause when it checks for the signal, update the data, then "set" the signal again to release the paused "reading" thread.
Use Task for background work and you can utilize Continue method to process the data on completion of task.
var task = Task.Run(() => "Test");
task.ContinueWith((str) => "Process data");
Or utilize Name property of Thread class to assign the name.

Force thread stop in .NET Core

Let's say i have .NET Core 2.0/2.1 program.
There is a thread executing the following method. I want to stop it forcefully.
Important notes:
Cooperative multitasking (for example, with CancellationToken) is a good thing, but not the case
XY problem (https://en.wikipedia.org/wiki/XY_problem) does exist, but i just want to know if stopping this thread is actually possible
while (true)
{
var i = 0;
try
{
Console.WriteLine($"Still alive {i++}");
}
catch (Exception e)
{
Console.WriteLine($"Caught {e.GetType().Name}");
}
}
Tried several options:
Thread.Abort - throws PlatformNotSupportedException, not an option
Thread.Interrupt - only works for threads in WaitSleepJoin state, which is not the case
Calling native API methods such as TerminateThread from kernel32.dll on Windows. This approach has a lot of problems like non-released locks (https://msdn.microsoft.com/en-us/library/windows/desktop/ms686717(v=vs.85).aspx)
Concerns, from most important to least:
Releasing locks
Disposing objects in using directives
Actually collecting allocated objects
(as a corner case we can assume that out thread does not perform any heap allocations at all)
Use a ManualResetEventSlim. The instance will need to be available to both the thread you are trying to stop and the thread which will cause the stop.
In your while(true) loop, do something like this:
var shouldTerminate = mres.Wait(100);
if (shouldTerminate) { break; }
What this does is wait until the ManualResetEvent is put into a Set state, or 100ms, whichever comes first. The value returned indicates if the event is Set or Unset. You'll start off with the MRE in an Unset state, and when the control thread wishes to terminate the worker thread, it will call the Set method, and then it can Join the worker thread to wait for it to finish. This is important as in your loop you could perhaps be waiting on a network call to finish, and the worker won't actually terminate until you are back at the top of the loop again. If you need to, you could check the MRE with Wait at multiple points in the worker thread to prevent further expensive operations from continuing.

Call an awaitable method inside a Thread in C#

In my C# 7.0 Code I like to use an old school Thread of type Thread to do some work. Inside this Thread, I need to use some async methods. What would be the best approach to call these methods?
Writing the thread function async does not make any sense.
this._networkListenerThread = new Thread(/* async here is not an option */() =>
{
while (!this._listenerCancellation.IsCancellationRequested)
{
try
{
// This does not compile
var packetBuffer = await this._commProxy.ReadAsync();
doSomethingMore();
}
}
}
If we go down the call stack, finally there will be this call:
// _socket is of type Android.Bluetooth.BluetoothSocket
// .InputStream of type System.IO.Stream
// ReadAsync only returns when data arrived on the stream
// or throws an exception when the connection is lost
var receivedBytes = await this._socket.InputStream.ReadAsync(buffer, 0, buffer.Length);
For those wondering why I want to use a Thread instead of Task: I want to give it a meaningful name to enhance debugging. I did not find a way to name a Task. Besides of this, this Thread runs almost as long as the application runs, therefore a Thread does make sense for me.
this Thread runs almost as long as the application runs
No, it doesn't. Because the work that it's doing is asynchronous. The thread runs long enough to check the status of the cancellation token, fire off ReadAsync (which, being asynchronous, will return basically immediately) and then it's done. The thread goes away, and it has no more work to do. That's the whole idea of asynchronous operations; being asynchronous means the operation returns to its caller pretty much immediately, and does whatever meaningful work it has to do after returning control back to the caller (in this case, since this is the top level method of the thread, returning control back means that the thread has finished executing and gets torn down).
So there just isn't much of any purpose in creating a new thread just to have it check a boolean value and start some operation that will go off and do work on its own. It's not that you should use a different way of getting a new thread to do work (like using Task.Run), but rather you shouldn't use any means of getting a new thread to do work, because you don't have any long running CPU bound work to do. The long running (non-CPU bound, by the look of it) work that you have is already asynchronous, so you can just call the method directly from whatever thread wants to start this work, and have it do it right in line.
If you simply want to have some value that you can share along an asynchronous operation's logical call context, there are of course tools that accomplish that, such as AsyncLocal. Creating a new thread wouldn't accomplish that, because as you finish starting the asynchronous operation you have your thread is dead and gone, and the continuations will be running in some other thread anyway.

Stop a thread if it takes too long

I am new in Windows Phone development and I am trying to create a windows phone app using C#
Thread t = new Thread(doaheavywork);
t.Start();
if (!t.Join(1000)) // give the operation 1s to complete
{
t.Abort();
}
I cannot alter the doaheavywork function.
I just need the result to be omputed within 1 or 2 seconds, since sometimes it may run for very long time.
I have read using abort is the wrong way.
I am using the above in a PhotoChooserTask complete function. First run executes fine. That is, when I click the button to select a photo, the doaheavywork function doesn't exceed 1 sec. But if I try for the second time, the PhotoChooserTask just throws an exception and stops.
Is it because I aborted the process in 1st run? Or anything else? Is there any other way to do it?
.Abort() causes the thread to be destroyed completely. If you are generating a new thread each time like in your example, then it will work. However if you are using the same t object, then you need to create a new thread object, you can't run .Start() on an aborted thread.
However the fact you are aborting a thread is a concern. What happens with the application when it does take more than 2 seconds. Should you be showing the user, please wait, its taking longer than expected. Doing that in the if block is where to do it. .Join() won't stop the thread even if it doesn't manage to join.
Edit
You have 2 options you might want to consider in rewriting this section:
BackgroundWorker - http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx
Thread Task - http://msdn.microsoft.com/en-us/library/windowsphone/develop/cc221403(v=vs.105).aspx
Tasks seem to be the appropriate solution in your scenario.
One approach maybe be to consider using a Task and having a CancellationToken passed in to it from a CancellationTokenSource instantiated against a specific timespan - 2 seconds. That way when the the time specified has elapsed, the CancellationToken, passed to the Task, will be signaled and then appropriate action can be taken.

Downloading strings using a Threadpool and waiting for the download to complete

I am using a WebClient to upload a string an retreive the answer from the server.
To get the job done quicker, I decided to use the ThreadPool, but I need to know when all the downloads are over.
So far, I've been using a CountdownEvent which is supposed to decrease when the server's answer has been processed.
My main thread executes this :
CountdownEvent cde = new CountdownEvent(retour["contenu"].Count()); //Set the countdown with the number of Thread that needs to be created
foreach (var tab in retour["contenu"])
{
App.AnniversaryViewModel.Items.Add(new Utilisateur(int.Parse((string)tab["id"])));
System.Diagnostics.Debug.WriteLine("Création d'un utilisateur avec l'id : " + (string)tab["id"]);
//System.Diagnostics.Debug.WriteLine("Le dernier utilisateur est : " + Items.Last<Utilisateur>().NOMPrenom);
ThreadPool.QueueUserWorkItem(App.AnniversaryViewModel.Items.Last<Utilisateur>().telechargerLesInfos , cde); //Starts the download
}
//Waiting for every Thread to be done
cde.Wait();
System.Diagnostics.Debug.WriteLine("On a fini d'attendre");
And here is, in another class, the code that is supposed to be executed by each thread :
public void telechargerLesInfos(Object cde)
{
APIWebTeam.sendRequest(RequestType.PROFIL, (Newtonsoft.Json.Linq.JObject reponse) =>
{
processInfos(reponse); //Takes the answer from the server and parse it to fill private fields
((CountdownEvent)cde).Signal();
}, "&idProfil=" + id);
}
The thing is that the delegate refuses to execute, as if the "cde.Wait()" is also forcing the thread handling the delegate to wait.
How can I fix / avoid that?
First off, the thread pool isn't really doing anything here. You're only starting an asynchronous operation in the thread pool. Starting such an operation takes basically no time at all. You may as well just do it in the main thread.
As for why the main thread is being blocked; that's easy, you're blocking the main thread yourself by waiting on the countdown event.
There is no way to have the main thread block until the async operation completes without blocking the main thread. They're literally contradictory requirements.
Instead you need to make your entire program asynchronous, to avoid blocking the main thread. Have this method take a callback that it should execute when the async operation completes, for example. The other option is to use the Task Parallel Library. Tasks make working with asynchronous operations quite a lot easier, especially if you're in a position to leverage the await keyword.

Categories

Resources