I have button call this code
private void but_Click(object sender, EventArgs e)
{
Thread My_Thread = new Thread(() => Send_File());
My_Thread.IsBackground = true;
My_Thread.Start();
}
I want a way to kill
My_Thread
from the function
Send_File()
please help me how to fix it ??? :(
Just declare your thread globally like any other variable (eg. int or string) you are using in different functions:
Thread My_Thread; //goes before your functions/main method
and then use it:
private void but_Click(object sender, EventArgs e)
{
My_Thread = new Thread(Send_File);
My_Thread.IsBackground = true;
My_Thread.Start();
}
and kill it:
private void Send_File()
{
MyThread.Abort();
}
If you are talking about Send_File running in the thread, just exit it for example using break, stop all loops to complete it.
EDIT:
As Austin Salonen has stated in his comment this would overwrite the thread reference. My suggestion would be using a thread list.
public List<Thread> ThreadList=new List<Thread>(); //goes before your functions/main method (public for use in other classes)
and use it:
private void but_Click(object sender, EventArgs e)
{
Thread My_Thread = new Thread(Send_File);
My_Thread.IsBackground = true;
My_Thread.Start();
int ThreadIndex = ThreadList.Count; //remember index
ThreadList.Add(My_Thread);
}
You just need to remember the index of the list to create a reference to the thread again.
To abort a thread just use its index:
ThreadList[ThreadIndex].Abort();
ThreadList[ThreadIndex] = null;
or just let the thread return.
Define the Thread at the class level:
public class Whatever
{
Thread My_Thread;
private void but_Click(object sender, EventArgs e)
{
My_Thread = new Thread(() => Send_File());
//...
}
private void Send_File()
{
My_Thread.Abort() //though I can never ever ever encourage doing this
//...
}
}
Or just return. When a Thread's work method returns, it is killed.
I'd highly recommend you not use Thread directly if you need to abort what it's doing. I'd recommend a Task and using CancellationTokenSource to communicate cancellation requests. If you need to communicate with the UI, e.g. progress, I'd recommend a BackgroundWorker. If you must use Thread, then you need to inform the user to abort. You can do this by using a shared boolean value that the thread periodically checks to see if it should continue. You should read/write the value in a thread-safe way. Maybe Interlocked.Exchange would do that for you or Thread.VolatileRead and Thread.VolatileWrite...
When you use Thread.Abort it simply stops the thread unless the thread tries to catch the ThreadAbortException. It's a bit iffy when you start using exceptions for normal logic flow; but, it's doable. There is a potential for deadlock with Thread.Abort in the context of try/catch/finally blocks. (and any other constrained region) But, Thread.Abort is not all that recommended: http://haacked.com/archive/2004/11/12/how-to-stop-a-thread.aspx
Thread.Abort() is the one you're looking for.
References & useful pages:
"Thread.Abort Method" [msdn.microsoft.com]
Related
I have a thread which calls one of the methods, now this method executes a query which can take a very long time possibly 40 minutes or so to complete,
I want to give user a a choice to be able to cancel this operation (meaning stop the thread and stop the query to release database).
I should mention that I am developing WPF Application using .net 4.5, SQL SERVER DB and C#.
You should use backgroundworker, it is exactly what you want.
Eather drag and drop it from the toolbox or create it in code - behind. It supports Cancellation, reports progress, notifies when complete and know if it is running or not.
Here is an example.
void method(){
BackgroundWorker worker = new BackgroundWorker();
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.ProgressChanged += worker_ProgressChanged;
worker.DoWork += worker_DoWork;
worker.WorkerSupportsCancellation = true;
if(!worker.IsBusy)
{
worker.RunWorkerAsync();
}
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
//do whatever needs to be done on the other thread here.
object argument = e.Argument; //if passed argument in RunWorkerAsync().
object result = new object();
e.Result = result;
//after making worker global, you can report progress like so:
worker.ReportProgress(50); //you can also pass a userState, which can be any object, to show some data already.
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//you can update a progress bar in here
int progress = e.ProgressPercentage;
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//when done
}
void CancelTheTask()
{
if (worker.IsBusy)
{
//make worker global first, but then
worker.CancelAsync();
}
}
A important things to look at: Never use resources in the DoWork method that are not created inside it. Thus pass things you need in the background worker as Arguments. And things that are created by the backgroundworker should not be set to a global variable ether, pass by result.
When cancelling, RunWorkCompleted will also be fired. Now the query to the database is already being executed, so that is still running, even when your application lost all resources to it.
To cancel that, we would need to know how you execute the query, like #S.Akbari mentioned is one way. Entity Framework 6 also supports cancellation.
For that: check this when using Queryable
here is another example
Or this solution without Entity Framework.
Using Task Parallel Library (TPL) you can use the Task Cancellation pattern.
When you have your Thread blocked on waiting for the query, it's useless for stopping anything.
Make sure the SqlConnection of the query is accessible from your UI and Close it. Abandon the Thread, it will terminate (with an error you've got to suppress).
If the UI thread is doing a Long-time operation it won't be able to process
UI requests. This is also known as Not Responding.
Use ThreadPool like this:
CancellationTokenSource ct;//instantiate it before ThreadPool.QueueUserWorkItem line
private void operation_Click(object sender, RoutedEventArgs e)
{
ct = new CancellationTokenSource();
ThreadPool.QueueUserWorkItem(_ =>
{
var result = LongTimeOperation();//set the operation in another thread so that the UI thread is kept responding
//use the Dispatcher to "return" to the UI thread
Dispatcher.BeginInvoke(new Action(() =>
{
//Use result for example : Label1.Text = result.ToString();
}));
});
}
To give user a choice to be able to cancel the operation use CancellationTokenSource like this:
private void cancel_Click(object sender, RoutedEventArgs e)
{
if (ct != null)
{
ct.Cancel();
ct= null;
}
}
Note: in LongTimeOperation() you must have one more parameter of type CancellationToken
private float LongTimeOperation(CancellationToken ct)
{
if (ct.IsCancellationRequested)
return -1;
....
....
}
This link is useful about Cancellation in Managed Threads.
this is a common problem.But in WPF and WinForm, i'd like to use BackGroundWorker. See Here
I have a BackgroundWorker DoWork function as follows
private void WorkerGetFeedData(object sender, DoWorkEventArgs args)
{
_feed.FetchUserData(_userNameCollection);
}
The FetchUserData is a function in another class(whose object is _feed) in another project in the same solution. The data fetch process takes considerable time and I'd like for the user to be able to cancel the process if necessary. How do I convey a cancel operation from the user to a function call elsewhere and just stop it?
You can use BackgroundWorker.CancelAsync method. Here's more info with example: MSDN
To be more exact to your problem, pass the worker to FetchUserData. It is the sender parameter. Then in the FetchUserData function you can check if the flag BackgroundWorker.CancellationPending is set and finish your method.
void FetchUserData(IEnumerable<Users> userNameCollection, BackgroundWorker worker)
{
// ...
if(worker.CancellationPending)
{
// Finish method..
}
}
And the WorkerGetFeedData method:
private void WorkerGetFeedData(object sender, DoWorkEventArgs args)
{
var worker = sender as BackgroundWorker;
if(worker != null)
_feed.FetchUserData(_userNameCollection, worker);
}
Send a message (event) to the worker thread that changes a boolean, indicating that the worker thread should end/cancel itself.
Edit: I was a bit quick reading your question, missing the important part. While trying to make up I found this interesting article which might help:
http://ondotnet.com/pub/a/dotnet/2003/02/18/threadabort.html
It does work when simulating a long running process with Thread.Sleep(), being at work I dont have time right now to write code to test it on a proper application/long running task.
class Program
{
static void Main(string[] args)
{
Thread thread = new Thread(new ThreadStart(Foo));
thread.Start();
Console.ReadKey();
thread.Abort(); // cause ThreadAbortException to be thrown
Console.ReadKey();
}
static void Foo()
{
try
{
while( true )
{
Console.WriteLine("Long running process...");
Thread.Sleep(100000);
}
}
catch( ThreadAbortException ex )
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine("Thread Closing ...");
}
}
}
The problem with this approach is - it uses Thread.Abort() - which interrupts the thread no matter what it is doing. This can lead to left open handles, memory leaks, etc. So while it may help it would most likely be very unwise to use.
Ian Griffiths supposes that another way to (force) cancel a thread would be to run it in its own, seperate process: http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation which you can kill whenever without affecting your process's internal state.
Can some kind soul please explain why the following psudocode would not work. The problem is that the lock can never be aquired on the backgroundWorker (Monitor.TryEnter(bw)) when called from a new thread. If I call it from the main UI thread it works fine.
Thanks
P
public class MyClass
{
private BackgroundWorker bw;
private void Button_Click(object sender, EventArgs e)
{
System.Threading.Thread t =
new System.Threading.Thread(new System.Threading.ThreadStart(DoStuff));
t.IsBackground = true;
t.Start();
}
private void DoStuff()
{
if (Monitor.TryEnter(bw))
{
WorkDetails wd = new WorkDetails('some stuff here');
bw.RunWorkerAsync(wd);
// etc... etc...
}
}
}
Are you missing a Monitor.Exit at the end of the if block.
Without a Monitor.Exit, whichever thread first does a Monitor.TryEnter successfully will be the only thread that can enter again.
I'm not sure you are using the background worker (BGW) as it was intended
The idea behind it, usually, is that you don't create threads yourself but rather specify to the BGW what you want to be done asynchronously. so your code should look like:
private BackgroundWorker bw = new BackgroundWorker ();
ctor
{
bw.DoWork += (sender, e) => DoStuff();
}
private void Button_Click(object sender, EventArgs e)
{
bw.RunWorkerAsync();
}
For more information, see here
comments:
As a rule of thumb, never lock on arbitrary objects (like you do on bw) but rather on objects whose sole purpose is locking. I recommend you read Jon Skeet's excellent multi threading guide
You can add the BGW declaratively via the designer, saving yourself the instantiation and event hooking code
I have a method that updates records from the database, and I wonder if this method really runs in my BackGroundWorker thread considering the following:
public partial class Form1 : Form
{
BackgroundWorker bg = new BackgroundWorker();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
bg.DoWork += new DoWorkEventHandler(bg_DoWork);
bg.RunWorkerAsync();
}
void bg_DoWork(object sender, DoWorkEventArgs e)
{
UpdateDatabaseRecords(); // <-- Does this method runs in my BackGroundWorker?
}
private void UpdateDatabaseRecords()
{
SqlConnection conn = new SqlConnection();
// etc...
}
}
Is there a difference if I coded the update stuffs directly inside the bg_DoWork method?
Something like:
void bg_DoWork(object sender, DoWorkEventArgs e)
{
SqlConnection conn = new SqlConnection();
// etc...
// do the update codes here instead of doing
// it by calling another method.
}
Yes it is executing on a separate thread. No there wouldn't be a difference thread wise if you put it directly in that method.
Functions run in the thread that calls them, due to how function calls are implemented. So, since your background worker is calling the bg_DoWork function, it will be running in the worker's thread.
Because the code snippet appears small, there probably won't be a significant difference in calling another function. If you're just doing that little bit of work, then you can have it all in one function. If you start to increase the complexity of what the worker does, then you may want to start splitting it into many functions.
Yes it runs in a separate thread (background). The only difference is that you don't have access to the DoWorkEventArgs parameter, but you can pass it to your method.
No, there is no difference. Invoking a method creates a new stack-frame for the method call, pushes it onto the call-stack for the current thread, and then transfers control to it. It's also possible that the method may be inlined by the JIT compiler, so you may not see any difference in the disassembly between your 'manually inlined' version and your current version.
Btw, here's the code for BackgroundWorker.RunAsync from reflector:
public void RunWorkerAsync()
{
this.RunWorkerAsync(null);
}
public void RunWorkerAsync(object argument)
{
if (this.isRunning)
{
throw new InvalidOperationException(SR.GetString("BackgroundWorker_WorkerAlreadyRunning"));
}
this.isRunning = true;
this.cancellationPending = false;
this.asyncOperation = AsyncOperationManager.CreateOperation(null);
// the important bit
this.threadStart.BeginInvoke(argument, null, null);
}
As you can see, your code will run in the context of a WorkerThreadStartDelegate.BeginInvoke. This should mean that one of the thread-pool threads will pick it up, which you can verify by testing the value of Thread.CurrentThread.IsThreadPoolThread inside the bg_DoWork method.
I don't think so!
wrapping it in a method don't make it work in different thread, i think all of your code inside bg_DoWork will work on background worker (including all code on UpdateDatabaseRecords method).
there is a ThreadSynchronizationContext class where you can post your method to work on different thread context.
you can test your code on visual studio by put a break point inside bg_DoWork method and UpdateDatabaseRecords method. check it out from "Thread Window" from menu "Debug -> Windows-> Thread" investigate it weather it is work on main thread or worker thread.
I have a bit of code that I need to run in a different thread than the GUI as it currently causes the form to freeze whilst the code runs (10 seconds or so).
Assume I have never created a new thread before; what's a simple/basic example of how to do this in C# and using .NET Framework 2.0 or later?
Good place to start reading is Joe Albahari.
If you want to create your own thread, this is as simple as it gets:
using System.Threading;
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
/* run your code here */
Console.WriteLine("Hello, world");
}).Start();
BackgroundWorker seems to be best choice for you.
Here is my minimal example. After you click on the button the background worker will begin working in background thread and also report its progress simultaneously. It will also report after the work completes.
using System.ComponentModel;
...
private void button1_Click(object sender, EventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
// this allows our worker to report progress during work
bw.WorkerReportsProgress = true;
// what to do in the background thread
bw.DoWork += new DoWorkEventHandler(
delegate(object o, DoWorkEventArgs args)
{
BackgroundWorker b = o as BackgroundWorker;
// do some simple processing for 10 seconds
for (int i = 1; i <= 10; i++)
{
// report the progress in percent
b.ReportProgress(i * 10);
Thread.Sleep(1000);
}
});
// what to do when progress changed (update the progress bar for example)
bw.ProgressChanged += new ProgressChangedEventHandler(
delegate(object o, ProgressChangedEventArgs args)
{
label1.Text = string.Format("{0}% Completed", args.ProgressPercentage);
});
// what to do when worker completes its task (notify the user)
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
delegate(object o, RunWorkerCompletedEventArgs args)
{
label1.Text = "Finished!";
});
bw.RunWorkerAsync();
}
Note:
I put everything in single method
using C#'s anonymous method for
simplicity but you can always pull
them out to different methods.
It is safe to update GUI within
ProgressChanged or
RunWorkerCompleted handlers.
However, updating GUI from DoWork
will cause
InvalidOperationException.
The ThreadPool.QueueUserWorkItem is pretty ideal for something simple. The only caveat is accessing a control from the other thread.
System.Threading.ThreadPool.QueueUserWorkItem(delegate {
DoSomethingThatDoesntInvolveAControl();
}, null);
Here is another option:
Task.Run(()=>{
//Here is a new thread
});
Quick and dirty, but it will work:
Using at top:
using System.Threading;
simple code:
static void Main( string[] args )
{
Thread t = new Thread( NewThread );
t.Start();
}
static void NewThread()
{
//code goes here
}
I just threw this into a new console application for an exmaple
Try using the BackgroundWorker class. You give it delegates for what to run, and to be notified when work has finished. There is an example on the MSDN page that I linked to.
If you want to get a value:
var someValue;
Thread thread = new Thread(delegate()
{
//Do somthing and set your value
someValue = "Hello World";
});
thread.Start();
while (thread.IsAlive)
Application.DoEvents();
Put that code in a function (the code that can't be executed on the same thread as the GUI), and to trigger that code's execution put the following.
Thread myThread= new Thread(nameOfFunction);
workerThread.Start();
Calling the start function on the thread object will cause the execution of your function call in a new thread.
Here how can use threads with a progressBar , its just for understing how the threads works, in the form there are three progressBar and 4 button:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Thread t, t2, t3;
private void Form1_Load(object sender, EventArgs e)
{
CheckForIllegalCrossThreadCalls = false;
t = new Thread(birinicBar); //evry thread workes with a new progressBar
t2 = new Thread(ikinciBar);
t3 = new Thread(ucuncuBar);
}
public void birinicBar() //to make progressBar work
{
for (int i = 0; i < 100; i++) {
progressBar1.Value++;
Thread.Sleep(100); // this progressBar gonna work faster
}
}
public void ikinciBar()
{
for (int i = 0; i < 100; i++)
{
progressBar2.Value++;
Thread.Sleep(200);
}
}
public void ucuncuBar()
{
for (int i = 0; i < 100; i++)
{
progressBar3.Value++;
Thread.Sleep(300);
}
}
private void button1_Click(object sender, EventArgs e) //that button to start the threads
{
t.Start();
t2.Start(); t3.Start();
}
private void button4_Click(object sender, EventArgs e)//that button to stup the threads with the progressBar
{
t.Suspend();
t2.Suspend();
t3.Suspend();
}
private void button2_Click(object sender, EventArgs e)// that is for contuniue after stuping
{
t.Resume();
t2.Resume();
t3.Resume();
}
private void button3_Click(object sender, EventArgs e) // finally with that button you can remove all of the threads
{
t.Abort();
t2.Abort();
t3.Abort();
}
}
If you are going to use the raw Thread object then you need to set IsBackground to true at a minimum and you should also set the Threading Apartment model (probably STA).
public static void DoWork()
{
// do some work
}
public static void StartWorker()
{
Thread worker = new Thread(DoWork);
worker.IsBackground = true;
worker.SetApartmentState(System.Threading.ApartmentState.STA);
worker.Start()
}
I would recommend the BackgroundWorker class if you need UI interaction.
// following declaration of delegate ,,,
public delegate long GetEnergyUsageDelegate(DateTime lastRunTime,
DateTime procDateTime);
// following inside of some client method
GetEnergyUsageDelegate nrgDel = GetEnergyUsage;
IAsyncResult aR = nrgDel.BeginInvoke(lastRunTime, procDT, null, null);
while (!aR.IsCompleted) Thread.Sleep(500);
int usageCnt = nrgDel.EndInvoke(aR);
Charles your code(above) is not correct. You do not need to spin wait for completion. EndInvoke will block until the WaitHandle is signaled.
If you want to block until completion you simply need to
nrgDel.EndInvoke(nrgDel.BeginInvoke(lastRuntime,procDT,null,null));
or alternatively
ar.AsyncWaitHandle.WaitOne();
But what is the point of issuing anyc calls if you block? You might as well just use a synchronous call. A better bet would be to not block and pass in a lambda for cleanup:
nrgDel.BeginInvoke(lastRuntime,procDT,(ar)=> {ar.EndInvoke(ar);},null);
One thing to keep in mind is that you must call EndInvoke. A lot of people forget this and end up leaking the WaitHandle as most async implementations release the waithandle in EndInvoke.
another option, that uses delegates and the Thread Pool...
assuming 'GetEnergyUsage' is a method that takes a DateTime and another DateTime as input arguments, and returns an Int...
// following declaration of delegate ,,,
public delegate long GetEnergyUsageDelegate(DateTime lastRunTime,
DateTime procDateTime);
// following inside of some client method
GetEnergyUsageDelegate nrgDel = GetEnergyUsage;
IAsyncResult aR = nrgDel.BeginInvoke(lastRunTime, procDT, null, null);
while (!aR.IsCompleted) Thread.Sleep(500);
int usageCnt = nrgDel.EndInvoke(aR);
There are many ways of running separate threads in .Net, each has different behaviors. Do you need to continue running the thread after the GUI quits? Do you need to pass information between the thread and GUI? Does the thread need to update the GUI? Should the thread do one task then quit, or should it continue running? The answers to these questions will tell you which method to use.
There is a good async method article at the Code Project web site that describes the various methods and provides sample code.
Note this article was written before the async/await pattern and Task Parallel Library were introduced into .NET.
How to: Use a Background Thread to Search for Files
You have to be very carefull with access from other threads to GUI specific stuff (it is common for many GUI toolkits). If you want to update something in GUI from processing thread check this answer that I think is useful for WinForms. For WPF see this (it shows how to touch component in UpdateProgress() method so it will work from other threads, but actually I don't like it is not doing CheckAccess() before doing BeginInvoke through Dispathcer, see and search for CheckAccess in it)
Was looking .NET specific book on threading and found this one (free downloadable). See http://www.albahari.com/threading/ for more details about it.
I believe you will find what you need to launch execution as new thread in first 20 pages and it has many more (not sure about GUI specific snippets I mean strictly specific to threading). Would be glad to hear what community thinks about this work 'cause I'm reading this one. For now looked pretty neat for me (for showing .NET specific methods and types for threading). Also it covers .NET 2.0 (and not ancient 1.1) what I really appreciate.
I'd recommend looking at Jeff Richter's Power Threading Library and specifically the IAsyncEnumerator. Take a look at the video on Charlie Calvert's blog where Richter goes over it for a good overview.
Don't be put off by the name because it makes asynchronous programming tasks easier to code.