C # thread called multiple times but executed once

Basically, I have a form with a button, when the button is pressed, it creates an instance of the class that runs Thread. When a thread executes, it automatically calls Thread.Abort ().

The code I have comes down to the following:

Button

private void Buttonclick(object sender, EventArgs e) { MyClass c = new MyClass() c.Do_your_thing(); } 

Grade:

 public class MyClass { Thread t; public void Do_your_thing() { t = new Thread(Running_code); t.Start(); } private void Running_code() { //Perform code here t.Abort(); } } 

When I press the button once, everything works. But when I press the button again, nothing happens.

When I do not use t.Abort (), everything works. But not using t.Abort () will cause a memory leak, and the program will not close properly (the thread never closes, so the process will remain alive).

Can someone explain to me what is going on? And how can I fix this?

EDIT: upon request I send some actual code

 public class MyClass { public void Test() { t = new Thread(() => { wb.DocumentCompleted += get_part; wb.Navigate("http://www.google.com"); Application.Run(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); } public void get_part(object sender, WebBrowserDocumentCompletedEventArgs e) { var br = sender as WebBrowser; string url = e.Url.ToString(); //Here is some code that compares the url to surten predefined url. When there is a match, it should run some code and then go to a new url if(url == string_final_url) { //Finally at the url I want, open it in a new Internet Explorer Window Process proc = Process.Start("IExplore.exe", url); } } } 

This is a small part of the small webscraper program. It moves to a web page that requires some login information. When I reach the page that I really want to be on, he should open it in the new Internet Explorer.

When I call this code and close the form, it is still displayed in the process tree. And when I press the button several times, the used memory continues to grow, and I suspect that this is some kind of memory leak.

+4
source share
2 answers

First, don't use Thread.Abort() , ever. See Is this thread.abort () normal and safe? for more information on the reasons.

There are many net warnings about using Thread.Abort() . I would recommend avoiding this if it was not really needed, which in this case I do not think so. You would be better off implementing a one-time timer, perhaps half a timeout, and reset it for every keystroke. Thus, your expensive operation will occur only after half a second or more (or any other length that you choose) inactivity of the user.

Instead of using interrupt, you can use Join() Method . This method blocks the calling thread until the thread terminates.

An example of this is

 Thread t1 = new Thread(() => { Thread.Sleep(4000); Console.WriteLine("t1 is ending."); }); t1.Start(); Thread t2 = new Thread(() => { Thread.Sleep(1000); Console.WriteLine("t2 is ending."); }); t2.Start(); t1.Join(); Console.WriteLine("t1.Join() returned."); t2.Join(); Console.WriteLine("t2.Join() returned."); 

Hope this helps.


Change To respond to your comments; The Join () call is what the thread allocates. You do not have to do anything. Just make sure that threads clean up all the resources that they can use before they exit.

However, I highly recommend that you study the thread pool or the parallel task library (TPL) instead of explicitly managing the threads. They are easier to use and handle such things much smoother.

+2
source

Is it possible to use .net 4+ if you can use TPL, which will greatly simplify this as

 public class MyClass { public void Do_your_thing() { // for async execution Task.Factory.StartNew(Running_code); // for synchronous execution // CAUTION !! If invoked from UI thread this will freeze the GUI until Running_code is returned. //Task.Factory.StartNew(Running_code).Wait(); } private void Running_code() { Thread.Sleep( 2000 ); Debug.WriteLine( "Something was done" ); } } 

Moreover, if the Running_Code method does something related to IO, TPL can use I / O completion ports, and the operation can be completely inconclusive.

EDIT:

Look at this SO stream. WebBrowser Control in a new stream .

Web browser control seems to work poorly with non-interface threads.

+1
source

All Articles