C# .NET - Thread Pool - Thread Stop??

Asked By Hamit YILDIRIM
01-Oct-08 06:14 PM
Hello,
I am trying to send asynchronous web request and scrape the html content from the particular web page. I am using thread pool for easiest management of threading. Everything is working fine. There are 2 buttons. One for starting scraping and another for stop the process. How can i code stop button? I want to stop the process running whenever anyone press stop. Here is my code:

'Code begins
  Private Sub ScanTimeoutCallback(ByVal State As Object, ByVal timedOut As Boolean)
        If timedOut Then
            Dim reqState As RequestState = CType(State, RequestState)
            Dim HTTPData As DataObject
            Dim sites As String = ""
            If Not reqState Is Nothing Then
                HTTPData = reqState.HTTPDataObj
                reqState.RequestObj.Abort()
                sites = reqState.sites
            End If
        End If
    End Sub
'This is the thread pooling sub. I just call it like this - sendrequest(arrlist)
    Public Sub SendRequest(ByVal uri As ArrayList)
        For Each siteurl As String In uri
            Dim httpdata As DataObject
            httpdata = New DataObject
            Dim Request As Net.HttpWebRequest = Net.HttpWebRequest.Create(siteurl)
            Request.KeepAlive = True
            Request.Method = "GET"
            'ThreadPool.SetMaxThreads(1, 1)
            '-- Asynchronously send the request
            Dim State As New RequestState(httpdata, Request, siteurl)
            Dim Result As IAsyncResult = CType(Request.BeginGetResponse(New AsyncCallback(AddressOf ReceiveResult), State), IAsyncResult)
            ThreadPool.RegisterWaitForSingleObject(Result.AsyncWaitHandle, New WaitOrTimerCallback(AddressOf ScanTimeoutCallback), State, 18000000, True)
        Next
    End Sub

    Private Sub ReceiveResult(ByVal Result As IAsyncResult)
        '-- Asynchronously receive the response
        Dim State As RequestState = CType(Result.AsyncState, RequestState)
        Dim SR As IO.StreamReader
        Dim Response As Net.HttpWebResponse
        Dim Request As Net.HttpWebRequest = State.RequestObj
        Try

            Response = CType(Request.EndGetResponse(Result), Net.HttpWebResponse)
            SR = New IO.StreamReader(Response.GetResponseStream()) '###
            datastring = SR.ReadToEnd
            datastring = extractemail(datastring)
            dataurl = Request.Address.ToString
            accesscontrol()
        Catch WebEx As Net.WebException
            datastring = "error occured"
            dataurl = Request.Address.ToString
            accesscontrol()
        Finally
            If Not Response Is Nothing Then
                Response.Close()
            End If
            If Not SR Is Nothing Then
                SR.Close()
            End If
        End Try
    End Sub
    Sub accesscontrol()
        If Me.InvokeRequired Then
            Me.Invoke(New MethodInvoker(AddressOf accesscontrol))
        Else
'do something
End Sub

'Code ended

The whole process is working perfectly well. But how can i manage stop the process. I got the thread pooling code from the bromberg's article in eggheadcafe.com in c#. I just want to ask some guru whether my code is right or not. I want to make it more faster.

Regards...

the code in the C#  the code in the C#

01-Oct-08 06:21 PM
 
    private void ScanTimeoutCallback(object State, bool timedOut) {
        
if (timedOut) {
            RequestState reqState 
((RequestState)(State));
            
DataObject HTTPData;
            string 
sites "";
            if 
(!(reqState == null)) {
                HTTPData 
reqState.HTTPDataObj;
                
reqState.RequestObj.Abort();
                
sites reqState.sites;
            
}
        }
    }
    
    
// This is the thread pooling sub. I just call it like this - sendrequest(arrlist)
    
public void SendRequest(ArrayList uri) {
        
foreach (string siteurl in uri) {
            DataObject httpdata
;
            
httpdata = new DataObject();
            
Net.HttpWebRequest Request Net.HttpWebRequest.Create(siteurl);
            
Request.KeepAlive = true;
            
Request.Method "GET";
            
RequestState State = new RequestState(httpdata, Request, siteurl);
            
IAsyncResult Result ((IAsyncResult)(Request.BeginGetResponse(new AsyncCallback(new System.EventHandler(this.ReceiveResult)), State)));
            
ThreadPool.RegisterWaitForSingleObject(Result.AsyncWaitHandle, new WaitOrTimerCallback(new System.EventHandler(this.ScanTimeoutCallback)), State, 18000000true);
        
}
    }
    
    
private void ReceiveResult(IAsyncResult Result) {
        
// -- Asynchronously receive the response
        
RequestState State ((RequestState)(Result.AsyncState));
        
IO.StreamReader SR;
        
Net.HttpWebResponse Response;
        
Net.HttpWebRequest Request State.RequestObj;
        try 
{
            Response 
((Net.HttpWebResponse)(Request.EndGetResponse(Result)));
            
SR = new IO.StreamReader(Response.GetResponseStream());
            
// ###
            
datastring SR.ReadToEnd;
            
datastring extractemail(datastring);
            
dataurl Request.Address.ToString;
            
accesscontrol();
        
}
        
catch (Net.WebException WebEx) {
            datastring 
"error occured";
            
dataurl Request.Address.ToString;
            
accesscontrol();
        
}
        
finally {
            
if (!(Response == null)) {
                Response.Close()
;
            
}
            
if (!(SR == null)) {
                SR.Close()
;
            
}
        }
    }
    
    
void accesscontrol() {
        
if (this.InvokeRequired) {
            
this.Invoke(new MethodInvoker(new System.EventHandler(this.accesscontrol)));
        
}
        
else {
            
// do something
        
}
    }

re  re

03-Oct-08 05:33 AM

Is there any way for the Service.OnStop() method to know which threads in the threadpool are running processes started by the main thread and is there any way to graciously stop those threads so that the system remains in a clean state when the service is stopped?

Solution:

1.

I’m not sure if this is the correct way, but the way I do it is the following:

Create a bool that your worker threads check to determine whether they should return immediately (e.g. public bool Shutdown_Now = false). Then in your OnStop() do: Shutdown_Now=true; Now you might want to assume that your threads have quit, but in the event that they haven’t, your service will fail to stop (which is probably a bug). Generally to prevent this from ever occurring, I’ll store a reference to Thread.CurrentThread whenever a worker thread starts. Then when OnStop() is called, I’ll notify them to quit with the Shutdown_Now bool and wait to see if the threads are still running after N seconds. If they are, then I’ll call thread.Abort().

So long as you keep track of all the worker threads being used and make sure you dereference the threads that have completed, you shouldn’t have a problem

2.

What I have done and don't know if this is the best way is to create a ManualResetEvent and pass it to my worker threads. My worker threads will keep checking this and if it gets signaled they will shutdown. My OnStop() method simply signals the ManualResetEvent. I also create ManualResetEvents that my worker threads signal when they finish and I can also listen for those after I ask them to shutdown.

3.

We had a similar problem. Have some global object that all threads can access. In your OnStop set that signal variable so that all threads would know that on stop is signaled. You will have to implement a logic in each thread function to check the stop signal variable and wind up processing immediately. Also once you set the variable in OnStop, put a sleep for 10-15 seconds (based on how much is your winding logic for each thread).

 

All these solution are pretty similar in the sense the onus (and logic) was on the worker thread to keep checking at regular interval if it has to stop processing. which i don't like doing. this makes me wish there was a way i could signal to a worker thread to exit as fast as it can but this is not supported as of now :

Second  Second

04-Oct-08 02:20 PM

ok I think second manner is the best.

Thanks..

Create New Account
help
web request pattern and I ask is it really async if it is using a ManualResetEvent and setting WaitOne()? The ManualResetEvent object is being declared as a static variable so isn't it causing problems with be using the same class to execute the async web request? If I remove the ManualResetEvent object will it be truly asynchronous and will I be losing something? Also, in my seen the code it looks something like this: public class AsyncWebRequest public AsyncWebRequest(){} public static ManualResetEvent allDone = new ManualResetEvent(false); const int BUFFER_SIZE = 1024; public void WebReq(string URL, string somedata) { try { if (URL URL); webRequest.Method = "POST"; webRequest.ContentType = "application / x-www-form-urlencoded"; webRequest.ContentLength = data.Length; ManualResetEvent WaitHndle = new ManualResetEvent(false); RequestState rs = new RequestState(WaitHndle, this.Debug); rs.Request = webRequest; rs.DataToSend = data; webRequest BeginGetRequestStream(new AsyncCallback(ReadCallbackRequest), rs); IAsyncResult r = (IAsyncResult)webRequest.BeginGetResponse(new AsyncCallback(RespCallback), rs); ThreadPool.RegisterWaitForSingleObject(r.AsyncWaitHandle, new WaitOrTimerCallback(ScanTimeoutCallback), rs, (30 * 1000), true); allDone.WaitOne(); rs.ResponseStream.Close(); } } catch
Delegate BeginInvoke and ManualResetEvent.WaitOne() .NET Framework Hello, Here is an example: ManualResetEvent waiter; delegate DoWorkDelegate; void DoWork() { waiter.WaitOne(); } void SubMethodnvoke() { DoWorkDelegate.BeginInvoke(DoWork); } I do something In fact, I don't know how it works in background. In the msdn documentation, ManualResetEvent.WaitOne() blocks the Thread until it receives a signal. But I hope this is not I have more than 25 waiting threads in the queue my app is dead. Is ManualResetEvent.WaitOne() really blocking a Thread or is there any job in the ThreadPool to let all others in the queue ? Thanks in advance for your help. .NET Framework Discussions ThreadPool.RegisterWaitForSingleObject (1) RegisterWaitForSingleObject (1) DoWorkDelegate.BeginInvoke (1) ManualResetEvent.WaitOne (1) WaitHandle.WaitOne (1) ManualResetEvent (1) ThreadPool (1) WaitHandle (1) On Mon, 11 Feb 2008 09:56:01 -0800, Alphapage
ManualResetEvent is slow? .NET Framework Hallo Im using a ManualResetEvent to signal to my thread, when things are done. But sometimes, I have measured that Anything else I can use to signal a thread faster? Thomas .NET Compact Framework Discussions ManualResetEvent (1) WaitOne (1) Well, you have told us little about the threading environment. Setting an your thread will not actually execute until that thread exits or blocks. Paul T. keywords: ManualResetEvent, is, slow? description: Hallo Im using a ManualResetEvent to signal to my thread, when things are done. But sometimes, I have measured that