Click here to Skip to main content
15,892,059 members
Articles / Programming Languages / Visual Basic
Article

Multithreaded timed-out operation

Rate me:
Please Sign up or sign in to vote.
3.04/5 (10 votes)
17 Dec 20042 min read 46.6K   173   13   7
Here is a class for making your multithreaded timed-out operation... without having to care about threads and timeout.

Introduction

Do you occasionally need multithreaded timed-out operations? Let me say, this is a very basic implementation, but is the best solution for trying many different methods for completing your operation before you choose the best one, and it lets you start from a small basic (but so easy to get) multithreaded stuff that you can grow or change as much as you like since this class is released under GNU LGPL compatible license (means I don't care anything).

I will refer to the example of a DNS resolving operation (scanner), but it can be any multithreaded timed-out operation.

Question: what should "atomically" do our operation? Here is an example (DNS resolving example, it's easy to write the atomic job):

VB
Private Function MyJob(IP as Object)As Object
      '(object you like)...What do you want to use/returnn?
      Dim IPString as String = IP
      '(with option strict off this is ok, otherwise ctype...)

      Try
         System.Net.Dns.Resolve(IPString)
         Return IPString
      Catch
         Return "NotResolved"
      End Try
End Function

Now I want this to be multithreaded and don't want to wait for the DNS for more than 3 sec per thread.

This is where the class comes in handy.

To use the class, simply create a MOP MultiThreadedTimedOutOperation instance:

VB
Dim WithEvents MOP as MultiThreadedTimedOutOperation

Initialize MOP by giving a reference to our atomic job function, and optionally, the maximum number of threads and the timeout.

VB
MOP = New MultiThreadedTimedOutOperation(AddressOf MyJob,40,3000)

I want to scan my entire subnet. Imagine that, we have our subnet prefix stored in LocalSNPrefix (String) as ("1.2.3."), so add the 254 jobs just like this:

VB
   Dim I as integer
   For I = 1 to 254
       MOP.QueueJob(LocalSNPrefix + I.ToString)
   Next

Now I want to start my operation:

VB
MOP.StartOperation

Now I can have implemented (not necessary) a function to catch performstepevent (to use with the progress bar). Anyway, you need to know when the operation is finished and of course get the results.

VB
   Private Sub OnOpFinish()Handles MOP.OpFinished
      'Here you know the operation is stopped so
      Dim S as Stack = MOP.GetResults()
      'Do with the results what you like here...
      'in this example we can retrieve resolved ip

      Dim I as Integer
      For I = 1 to S.count
          Dim Result as string = S.Pop
          If Not Result.Equals("NotResolved")
              MessageBox.Show("ResolvedIP :" + Result)
      Next
   End sub

That's it. Anyway I don't suggest this class be used in any "release version" without "strong implementation" stuff like late binding objects, and often there would be no need to make sure that an atomic operation has finished if it is placed into a separate thread as the class does. In fact, often you will already have a function that supports timing out by its own.

And if you think you can do better, don't wait.

Here's the code, copy and paste it directly into your VB.NET project or download the file from the zip file.

VB
Public Class MultiThreadedTimedOutOperation
    Public Delegate Function Job(ByVal InitState As Object) As Object
    Public Event PerformStep()
    Public Event OpFinished()
    Private JobStart As Job
    Private Results As New Stack
    Private TS As New Queue
    Private ActiveThreads As Integer
    Private ReadOnly MaxThreads As Integer = 40
    Private ReadOnly Waittime As Integer = 3000
    Public Sub New(ByVal Method As Job, Optional ByVal maxthreads _
           As Integer = 40, Optional ByVal Timeout As Integer = 3000)
        Me.MaxThreads = maxthreads
        Me.Waittime = Timeout
        JobStart = Method
    End Sub
    Public Sub QueueJob(ByVal UserJobStartState As Object)
        TS.Enqueue(UserJobStartState)
    End Sub
    Public Sub StartOperation()
        Dim t As New Threading.Thread(AddressOf MainJob)
        t.ApartmentState = Threading.ApartmentState.MTA
        t.Start()
    End Sub
    Public Function GetResults() As Stack
        Return Results
    End Function 
    Private Sub MainJob()
        While TS.Count > 0
            If ActiveThreads < MaxThreads Then
                Do1Job()
                RaiseEvent PerformStep()
            End If
            System.Threading.Thread.Sleep(Waittime / MaxThreads)
        End While
        RaiseEvent OpFinished()
    End Sub 
    Private Sub Do1Job()
        Dim t As New Threading.Thread(AddressOf TimingOutJob)
        t.Start()
    End Sub
    Private Sub TimingOutJob()
        ActiveThreads += 1
        Dim t As New Threading.Thread(AddressOf JobInvoke)
        t.Start()
        If Not t.Join(Waittime) Then t.Abort()
        ActiveThreads -= 1
    End Sub
    Private Sub JobInvoke()
        Dim ThisJob As String = TS.Dequeue
        Dim Result As Object = JobStart.Invoke(ThisJob, Nothing, Nothing)
        If Not Result Is Nothing Then Results.Push(Result)
    End Sub
End Class

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Italy Italy
...picture was not for codeproject hihihi.
well my usual way is to release only classes wich can be used by you very easily and quickly.

Comments and Discussions

 
GeneralWell done Pin
Taner Riffat7-Nov-06 13:06
Taner Riffat7-Nov-06 13:06 
GeneralMY GOD Pin
uno freeware26-Feb-06 18:34
uno freeware26-Feb-06 18:34 
GeneralRerun timed-out thread Pin
Jeff Bowman6-Jan-06 16:24
professionalJeff Bowman6-Jan-06 16:24 
GeneralRe: Rerun timed-out thread Pin
uno freeware12-Jan-06 6:13
uno freeware12-Jan-06 6:13 
GeneralRe: Rerun timed-out thread Pin
Jeff Bowman12-Jan-06 8:27
professionalJeff Bowman12-Jan-06 8:27 
Generalgreat.. helpful. but what if i want to stop the thread Pin
Jason Rico5-Dec-05 13:17
Jason Rico5-Dec-05 13:17 
GeneralRe: great.. helpful. but what if i want to stop the thread Pin
uno freeware11-Dec-05 12:20
uno freeware11-Dec-05 12:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.