doesn't it need to delete thread object? - c#

i have a search thread in my project .
the thread is created in 'Form1()' function:
objSearchThread = new Thread(this.Thread_Func);
when user clicks the 'search' button, Start() function is called:
private void Button_Search_Click(object sender, EventArgs e)
{
objSearchThread.Start();
}
second clicked of this button, crashed! because the thread is 'Started' state.
if i change my button clicked code, and i add 'new' command. it works without error or crashing:
private void Button_Search_Click(object sender, EventArgs e)
{
objSearchThread = new Thread(this.Thread_Func);
objSearchThread.Start();
}
doesn't it need to delete thread object(objSearchThread )?
does it need to call Abort() or other functions, when thread working ends?
is second code that i write here correct?

No, you don't need to do anything. The thread will just finish when it has no more work to do. You might want to consider scheduling it to execute on the thread pool however, instead of creating a new thread each time. You could do that directly, or via the Task Parallel Libray (TPL) with the Task API. Alternatively, you might want to use BackgroundWorker, as that makes it easier to report progress to the UI. (Depending on what you're doing, you may not even need another thread at all - if you're calling a web service for example, you may be able to use the async facilities in C# 5 to make the code simpler and more efficient in one go...)
If you're using Thread directly, however, you do need to create a new Thread object each time you want to start it, as you can't reuse a thread.
Additionally, unless you need this to be an instance variable, you should consider making it a local variable. When do you ever access the thread other than in method?

Related

How to call Same event Handler with multiple class object in Windows form C# [duplicate]

I have a windows forms application
on which I need to use a for loop having a large number of Remote Calls around 2000 - 3000 calls,
and while executing the for loop, I loose my control on form and form controls, as it becomes a large process and some time it shows "Not Responding" but if I wait for a long it comes back again, I think I need to use some threading model for that, is there any idea, how can I proceed to solve the issue?
You need to perform the long running operation on a background thread.
There are several ways of doing this.
You can queue the method call for execution on a thread pool thread (See here):
ThreadPool.QueueUserWorkItem(new WaitCallback(YourMethod));
In .NET 4.0 you can use the TaskFactory:
Task.Factory.StartNew(() => YourMethod());
And in .NET 4.5 and later, you can (and should, rather than TaskFactory.StartNew()) use Task.Run():
Task.Run(() => YourMethod());
You could use a BackgroundWorker for more control over the method if you need things like progress updates or notification when it is finished. Drag the a BackgroundWorker control onto your form and attach your method to the dowork event. Then just start the worker when you want to run your method. You can of course create the BackgroundWorker manually from code, just remember that it needs disposing of when you are finished.
Create a totally new thread for your work to happen on. This is the most complex and isn't necessary unless you need really fine grained control over the thread. See the MSDN page on the Thread class if you want to learn about this.
Remember that with anything threaded, you cannot update the GUI, or change any GUI controls from a background thread. If you want to do anything on the GUI you have to use Invoke (and InvokeRequired) to trigger the method back on the GUI thread. See here.
private voidForm_Load(object sender, EventArgs e)
{
MethodInvoker mk = delegate
{
//your job
};
mk.BeginInvoke(callbackfunction, null);
}
private void callbackfunction(IAsyncResult res)
{
// it will be called when your job finishes.
}
use MethodInvoker is the easiest way.
Obviously, you need to use background threads. I suggest you read this free e-book.

Thread calling problems

I'm a bit of a newbie at this but I am trying to get the UI on a Reversi game to run on a different thread to the move selection part but I am having some trouble calling the thread on the button click
private void playerMoveOKButton_Click(object sender, EventArgs e)
{
ReversiT.Invoke();
}
public void ReversiT() {...}
If you're trying to create a new thread, you can do something like this:
Thread thread = new Thread(ReversiT);
thread.Start();
Invoke is used for a different purpose though. It is used to run a method on a specific thread (for instance, if you run a piece of code on a separate thread but want to make UI changes, you will want to use Invoke to make those changes on the UI thread)
I would create a BackgroundWorker to handle everything for me, setting it's DoWork event to call your move method (making sure that your move method doesn't touch the UI, or if it has to, invoking the controls on the UI thread).
I'd also set up a method to update the UI on the BackgroundWorker's RunWorkerCompleted event.
Now on your button click event above, call the BGW's RunWorkerAsync() method.
You can not invoke a method like that. You can only invoke delegates. Also, calling Invoke doesn't spawn a new thread.
You can read this tutorial about delegates, and this one about threads. Also, your question leaves much space for discussion:
What do you expect from using threads?
Have you considered different options for doing background work?
etc.
Use following
this.Invoke(ReversiT);
I think you need to think about that you are actually trying to achieve here. Running code on a separate thread in a UI is a technique used to stop the UI from hanging. However, some tasks simply have to occur on the UI thread and so can't be run from another thread.
You need to break your logic out such that you can identify which parts need to run on the UI thread (anything that interacts with a control on your UI) and thus anything that can run on a separate thread.
You would end up with code like (as an example):
private void playerMoveOKButton_Click(object sender, EventArgs e)
{
//thread is merely used as an example
//you could also use a BackgroundWorker or a task
var thread = new Thread(NonUiLogic);
thread.Start();
}
private void NonUiLogic()
{
...
//execute logic that doesn't touch UI
...
BeginInvoke(ReversiT);
}
public void ReversiT() {...}
Once you have been through that exercise you may find that there is actually very little that can happen outside of the UI thread and so you really have nothing to gain from using threads.

BackgroundWorker In Form.Load event

I'm working in a c# windows application with vs2010 and a local database.In one of my forms i use a BindingNavigator with a group of textboxes filled by the database and a ReporViewer. I've added a background worker in order to fill the table adapters in case there are a lot of records in the database.
The problem is that the way I'm using the background worker when i debug my app i cannot see any data in the textboxes, otherwise when i run my app it's working fine. I know that this is a case of accessing the UI on a non-UI thread and it is wrong. Is there a another way around it?Thank you in advance.
Here is the code I'm using:
private void Client_Load(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
this.clientTableAdapter.Fill(this.database1DataSet.Client);
this.projectTableAdapter.Fill(this.database1DataSet.Project);
if (InvokeRequired)
{
this.Invoke(new MethodInvoker(this.reportViewer1.RefreshReport));
return;
}
}
Typically, a background worker returns on the same thread, and would actually throw an exception about the non-UI thread. However, this might be eaten in your case. You should be using the RunWorkerCompleted event for items that are to happen after your main work is done, especially when looking to update the UI. And, this should return to the same thread it was called from (UI in your case) as mentioned above.
So, I would move your UI processing code (RefreshReport) into a new method set up for the RunWorkerCompleted.
However, my suggestion would be to take a look at the Task Parallel Library. It ends up making code much cleaner and easier to debug IMO.
Example (rough and may not compile due to the nulls, but you can get the jist :)):
var task = Task.Factory.StartNew(()=>{//Do Async Stuff});
task.ContinueWith((previousTask)=>{//Do your UI Stuff}, null, null,
TaskScheduler.FromCurrentSynchronizationContext);
//The FromCurrentSync makes sure the method returns
//to the same thread (UI in this case) that it started
I know that is not a direct answer, but more of a suggestion towards what I would consider a cleaner, more debuggable approach.

Restarting a thread in .NET (using C#)

I'm looking for a way to restart a thread that has been stopped by Abort()..
public partial class MyProgram : Form
{
private Thread MyThread = new Thread(MyFunction);
private System.Windows.Forms.Button startStopBtn = new System.Windows.Forms.Button();
public MyProgram()
{
MyThread.Start();
startStopBtn += new EventHandler(doStop);
startStopBtn.Text = "Stop";
}
private static void MyFunction()
{
// do something
}
private void doStop(object sender, EventArgs e)
{
MyThread.Abort();
startStopBtn -= new EventHandler(doStop);
startStopBtn += new EventHandler(doStart);
startStopBtn.Text = "Start";
}
private void doStart(object sender, EventArgs e)
{
MyThread.Start(); // << Error returned when clicking the button for 2nd time
startStopBtn -= new EventHandler(doStart);
startStopBtn += new EventHandler(doStop);
startStopBtn.Text = "Stop";
}
}
Any idea?
Once you have aborted your thread, you cannot start it again.
But your actual problem is that you are aborting your thread. You should never use Thread.Abort().
If your thread should be paused and continued several times, you should consider using other mechanisms (like AutoResetEvent, for example).
[EDIT]
The simplest solution to abort a thread, as mentioned by Ian Griffiths in the link above, is:
The approach I always recommend is dead simple. Have a volatile bool field that is visible both to your worker thread and your UI thread. If the user clicks cancel, set this flag. Meanwhile, on your worker thread, test the flag from time to time. If you see it get set, stop what you're doing.
The only thing that you need to do to make it work properly, is to rearrange your background method so that it runs in a loop - so that you can periodically check if your flag has been set by a different thread.
If you need to have pause and resume functionality for the same worker thread, instead of the simple volatile bool flag approach, you could go for a slightly more complex approach, a synchronizing construct such as AutoResetEvent. These classes also provide a way to put the worker thread to sleep for a specified (or indefinite) amount of time between signals from the non-worker thread.
This thread contains a concrete example with Start, Pause, Resume and Stop methods. Note how Brannon's example never aborts the thread. It only fires an event, and then waits until the thread finishes gracefully.
Simply add MyThread = new Thread(MyFunction) before calling MyThread.Start() in doStart(). Do not create the thread outside of your methods, the space there is thought for declarations.
Please note that killing a thread with thread.Abort() can be very dangerous, as it might cause unexpected behavior or might not correctly dispose resources owned by the thread. You should try to accomplish clean multi threading, like Groo described in his answer.
The simple answer is, you can't. Once a thread has been aborted, you can't restart it. Just create a method or something, that returns a Thread object just how you need it. When you need a new Thread, just get it from that method.
No, there isn't, but why would you want to? Just start up a new thread, with the same ThreadStart, and the same parameter (if any).
If you really need to interrupt the thread function and resume, you should set a condition and then check it periodically during processing.
That would allow you to stop processing for some amount of time and then resume.
I've used events and Wait calls to accomplish a similar task.
The easiest way is to not abort the thread.
I really don't understand why people provide information if they do not know that is correct..
How can a real programmer suspend or stop processing a thread for sometime and then release it and thereby making the code vulnerable...
#Brad-- m sorry.. but your idea was not good..
#Rhythmic - You need to work on your way to approach things..
BFree was somewhat right if you people got him the same way he wanted to say..
You just need to re-declare that..
below is the example:
Public Shared Sub ResetAbort()
Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName))
YourThreadName.Start()
Thread.Sleep(2000)
YourThreadName.Abort()
End Sub
Now you can use this Sub anywhere you want to start the thread. It will automatically abort the thread.
If you want to start the thread on Button1_click() event and stop it on Button2_Click() event use this:
in Button1_click() event
Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName))
YourThreadName.Start()
in Button2_click() event
YourThreadName.Start()
doing this way you will abort you thread where ever you want and will initialize it again.
You can also use YourThreadName.ThreadState.Running property to check if the thread is running or not(Just to avoid multiple instances of the same thread.....

WinForm Application UI Hangs during Long-Running Operation

I have a windows forms application
on which I need to use a for loop having a large number of Remote Calls around 2000 - 3000 calls,
and while executing the for loop, I loose my control on form and form controls, as it becomes a large process and some time it shows "Not Responding" but if I wait for a long it comes back again, I think I need to use some threading model for that, is there any idea, how can I proceed to solve the issue?
You need to perform the long running operation on a background thread.
There are several ways of doing this.
You can queue the method call for execution on a thread pool thread (See here):
ThreadPool.QueueUserWorkItem(new WaitCallback(YourMethod));
In .NET 4.0 you can use the TaskFactory:
Task.Factory.StartNew(() => YourMethod());
And in .NET 4.5 and later, you can (and should, rather than TaskFactory.StartNew()) use Task.Run():
Task.Run(() => YourMethod());
You could use a BackgroundWorker for more control over the method if you need things like progress updates or notification when it is finished. Drag the a BackgroundWorker control onto your form and attach your method to the dowork event. Then just start the worker when you want to run your method. You can of course create the BackgroundWorker manually from code, just remember that it needs disposing of when you are finished.
Create a totally new thread for your work to happen on. This is the most complex and isn't necessary unless you need really fine grained control over the thread. See the MSDN page on the Thread class if you want to learn about this.
Remember that with anything threaded, you cannot update the GUI, or change any GUI controls from a background thread. If you want to do anything on the GUI you have to use Invoke (and InvokeRequired) to trigger the method back on the GUI thread. See here.
private voidForm_Load(object sender, EventArgs e)
{
MethodInvoker mk = delegate
{
//your job
};
mk.BeginInvoke(callbackfunction, null);
}
private void callbackfunction(IAsyncResult res)
{
// it will be called when your job finishes.
}
use MethodInvoker is the easiest way.
Obviously, you need to use background threads. I suggest you read this free e-book.

Categories

Resources