home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Visual Database / Visual BASIC 5.0 (Ent. Edition) / Vb5ent Extractor.EXE / VB / SAMPLES / COMPTOOL / ACTVCOMP / COFFEE / CWTHREAD.FRM (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1996-12-04  |  11.8 KB  |  358 lines

  1. VERSION 5.00
  2. Begin VB.Form frmThread 
  3.    BorderStyle     =   1  'Fixed Single
  4.    Caption         =   "Multithreading Demo"
  5.    ClientHeight    =   4950
  6.    ClientLeft      =   4140
  7.    ClientTop       =   1470
  8.    ClientWidth     =   7095
  9.    LinkTopic       =   "Form2"
  10.    MaxButton       =   0   'False
  11.    MinButton       =   0   'False
  12.    ScaleHeight     =   4950
  13.    ScaleWidth      =   7095
  14.    Begin VB.Timer tmrShort 
  15.       Enabled         =   0   'False
  16.       Interval        =   1000
  17.       Left            =   2280
  18.       Top             =   3840
  19.    End
  20.    Begin VB.CommandButton cmdCancel 
  21.       Caption         =   "&Cancel Long Tasks"
  22.       Height          =   375
  23.       Left            =   240
  24.       TabIndex        =   8
  25.       Top             =   4440
  26.       Width           =   2895
  27.    End
  28.    Begin VB.TextBox txtN 
  29.       Height          =   375
  30.       Left            =   2760
  31.       MaxLength       =   1
  32.       TabIndex        =   6
  33.       Text            =   "4"
  34.       Top             =   2160
  35.       Width           =   375
  36.    End
  37.    Begin VB.CommandButton cmdNLong 
  38.       Caption         =   "...with &N LongTasks"
  39.       Height          =   375
  40.       Left            =   240
  41.       TabIndex        =   5
  42.       Top             =   2160
  43.       Width           =   2415
  44.    End
  45.    Begin VB.CommandButton cmdShortLong 
  46.       Caption         =   "...with &Long Task"
  47.       Height          =   375
  48.       Left            =   240
  49.       TabIndex        =   4
  50.       Top             =   1680
  51.       Width           =   2895
  52.    End
  53.    Begin VB.CommandButton cmdShortOnly 
  54.       Caption         =   "&Short Tasks, Serialized..."
  55.       Height          =   375
  56.       Left            =   240
  57.       TabIndex        =   3
  58.       Top             =   1200
  59.       Width           =   2895
  60.    End
  61.    Begin VB.CommandButton cmdIDs 
  62.       Caption         =   "List Thread &IDs"
  63.       Height          =   375
  64.       Left            =   240
  65.       TabIndex        =   2
  66.       Top             =   720
  67.       Width           =   2895
  68.    End
  69.    Begin VB.ListBox lstResults 
  70.       Height          =   4575
  71.       Left            =   3360
  72.       TabIndex        =   1
  73.       Top             =   120
  74.       Width           =   3615
  75.    End
  76.    Begin VB.CommandButton cmdXThread 
  77.       Caption         =   "Cross-Thread &Overhead"
  78.       Height          =   375
  79.       Left            =   240
  80.       TabIndex        =   0
  81.       Top             =   240
  82.       Width           =   2895
  83.    End
  84.    Begin VB.Label Label1 
  85.       Caption         =   "Your experiments here..."
  86.       Height          =   255
  87.       Left            =   240
  88.       TabIndex        =   7
  89.       Top             =   2760
  90.       Width           =   2895
  91.    End
  92. Attribute VB_Name = "frmThread"
  93. Attribute VB_GlobalNameSpace = False
  94. Attribute VB_Creatable = False
  95. Attribute VB_PredeclaredId = True
  96. Attribute VB_Exposed = False
  97. Option Explicit
  98. ' The multithreading demo:
  99. '   - Shows thread ids and number of objects
  100. '       on a thread (this will be more
  101. '       interesting if you compile MTCoffee.exe
  102. '       with a thread pool size of 3 or 4).
  103. '   - Compares call overhead for same-thread
  104. '       vs. cross-thread calls.
  105. '   - Time per iteration for serial short
  106. '       tasks (see Coffee object defined in
  107. '       MTCoffee.cls).
  108. '   - Times per iteration for a long task, and
  109. '       for serial short tasks run at the same
  110. '       time.
  111. '   - Times per iteration for a number of long
  112. '       tasks, with serial short tasks running
  113. '       at the same time.
  114. ' You can add your own tests to this framework.
  115. '   You may find it interesting to compare the
  116. '   behavior of tasks that block (such as
  117. '   database queries on remote computers, or
  118. '   large file transfers).  On a computer with
  119. '   a single processor, such tasks will behave
  120. '   much better than the computation-intensive
  121. '   tasks used in the examples above.  Threads
  122. '   that perform computation-intensive tasks
  123. '   compete with each other for the machine's
  124. '   single processor, and so their performance
  125. '   suffers as the number of active threads
  126. '   increases.
  127. ' For more information, see "Scalability and
  128. '   Multithreading," in "Building Code
  129. '   Components" in Books Online.
  130. ' These constants control the relative size of
  131. '   a long task and a short task.  You may need
  132. '   to adjust these for the speed of your
  133. '   processor.
  134. Const SHORTTASKSIZE = 50000
  135. Const LONGTASKSIZE = 2000000
  136. ' Array of Coffee objects.
  137. Private macfe(1 To 20) As Coffee
  138. ' Collection of CoffeeTracker objects.
  139. Public CoffeeTrackers As New Collection
  140. ' Cancel flag.
  141. Public CancelAll As Boolean
  142. ' How many short tasks to run.
  143. Private mintHowManyShort As Integer
  144. Private Sub cmdCancel_Click()
  145.     ' When the user clicks Cancel, set a
  146.     '   flag that CoffeeTracker can use
  147.     '   to cancel all long tasks when they
  148.     '   raise their next Progress event.
  149.     CancelAll = True
  150. End Sub
  151. ' Run a few short tasks serially, to get a
  152. '   feel for their speed when not competing
  153. '   for the processor.
  154. Private Sub cmdShortOnly_Click()
  155.     lstResults.Clear
  156.     CancelAll = False
  157.     mintHowManyShort = 10
  158.     tmrShort.Interval = 250
  159.     tmrShort.Enabled = True
  160. End Sub
  161. ' Run a long task, then run short tasks
  162. '   serially while it's running.
  163. Private Sub cmdShortLong_Click()
  164.     Dim cft As CoffeeTracker
  165.     lstResults.Clear
  166.     CancelAll = False
  167.     Set cft = NewTracker(macfe(1).ThreadID, LONGTASKSIZE)
  168.     Set cft.Coffee = macfe(1)
  169.     Call macfe(1).StartLongTask(LONGTASKSIZE)
  170.     '
  171.     ' Line up some short tasks to run (one
  172.     '   every quarter second) while task
  173.     '   runs.
  174.     mintHowManyShort = 10
  175.     tmrShort.Enabled = True
  176.     tmrShort.Interval = 250
  177. End Sub
  178. ' Start N long tasks (1 - 9), then run a series
  179. '   of short tasks.
  180. Private Sub cmdNLong_Click()
  181.     Dim intCt As Integer
  182.     Dim cft As CoffeeTracker
  183.     lstResults.Clear
  184.     CancelAll = False
  185.     For intCt = 1 To CLng("0" & txtN)
  186.         Set cft = NewTracker(macfe(intCt).ThreadID, LONGTASKSIZE)
  187.         Set cft.Coffee = macfe(intCt)
  188.         Call macfe(intCt).StartLongTask(LONGTASKSIZE)
  189.     Next
  190.     '
  191.     ' Line up some short tasks to run while
  192.     '   the long ones run.
  193.     mintHowManyShort = 10 + CLng("0" & txtN)
  194.     tmrShort.Enabled = True
  195.     tmrShort.Interval = 250
  196. End Sub
  197. ' Compare the call overhead for calls to an
  198. '   object on the same thread, vs. calls to
  199. '   an object on another thread.
  200. Private Sub cmdXThread_Click()
  201.     Dim cfeSame As Coffee
  202.     Dim cfeNew As Coffee
  203.     cmdXThread.Caption = "Working..."
  204.     cmdXThread.Enabled = False
  205.     ' Create a Coffee object on another thread.
  206.     Set cfeNew = macfe(10).GetCoffeeOnNewThread
  207.     ' In case of thread pooling; except in
  208.     '   the degenerate case of one thread in
  209.     '   the pool, this should get a different
  210.     '   thread the second time.
  211.     If cfeNew.ThreadID = macfe(10).ThreadID Then
  212.         Set cfeNew = macfe(10).GetCoffeeOnNewThread
  213.         If cfeNew.ThreadID = macfe(10).ThreadID Then
  214.             MsgBox "Unable to run comparison between same-thread and cross-thread calls; can't get an object on another thread."
  215.             Exit Sub
  216.         End If
  217.     End If
  218.     '
  219.     ' Create a Coffee object on the same thread.
  220.     Set cfeSame = macfe(10).GetCoffeeOnSameThread
  221.     ' Use the newly created coffee objects to
  222.     '   perform the test.
  223.     MsgBox "Same thread:  " & macfe(10).CallAnotherCoffee(cfeSame) & " sec/call" & vbCrLf _
  224.         & "Cross-thread:  " & macfe(10).CallAnotherCoffee(cfeNew) & " sec/call"
  225.     cmdXThread.Caption = "Cross-Thread Overhead"
  226.     cmdXThread.Enabled = True
  227.     '
  228.     ' The Coffee objects created for this test
  229.     '   are terminated when cfeNew and cfeSame
  230.     '   go out of scope at the end of this
  231.     '   procedure.
  232. End Sub
  233. ' List the thread IDs of the Coffee objects
  234. '   created when this form loaded.
  235. Private Sub cmdIDs_Click()
  236.     Dim intCt As Integer
  237.     lstResults.Clear
  238.     For intCt = 1 To 10
  239.         lstResults.AddItem macfe(intCt).ThreadID _
  240.             & "  (" & macfe(intCt).NumberOnThread & " on thread)"
  241.     Next
  242. End Sub
  243. ' Create a series of Coffee objects, each on
  244. '   its own thread.  (If you recompile MTCoffee
  245. '   with a thread pool less than 10, some of
  246. '   these will share thread and global state.)
  247. Private Sub Form_Load()
  248.     Dim intCt As Integer
  249.     For intCt = 1 To 10
  250.         Set macfe(intCt) = New Coffee
  251.     Next
  252.     Form1.cmdMT.Enabled = True
  253.     Form1.cmdMT.MousePointer = vbDefault
  254. End Sub
  255. Private Sub Text1_KeyPress(KeyAscii As Integer)
  256.     Select Case KeyAscii
  257.         Case 48 To 57, 8
  258.         Case Else
  259.             Beep
  260.             KeyAscii = 0
  261.     End Select
  262. End Sub
  263. ' Provide unique keys for CoffeeTrackers.
  264. Private Function NewKey() As String
  265.     Static lngLastKey As Long
  266.     lngLastKey = lngLastKey + 1
  267.     NewKey = "K" & lngLastKey
  268. End Function
  269. ' Add a new CoffeeTracker.  Properly speaking,
  270. '   this should be a method of a CoffeeTrackers
  271. '   collection class.
  272. Private Function NewTracker(ByVal ThreadID As Long, _
  273.         ByVal Size As Long) As CoffeeTracker
  274.         
  275.     Dim cft As New CoffeeTracker
  276.     '
  277.     ' Cache the thread ID of the Coffee object
  278.     '   the tracker will be keeping track of.
  279.     cft.ThreadID = ThreadID
  280.     '
  281.     ' Set the size of the task assigned to the
  282.     '   Coffee object the tracker will track.
  283.     cft.Size = Size
  284.     '
  285.     ' Give the tracker a unique key for the
  286.     '   collection.
  287.     cft.ID = NewKey
  288.     '
  289.     ' Put the new tracker into a collection.
  290.     CoffeeTrackers.Add cft, cft.ID
  291.     '
  292.     ' Return a reference to the new tracker.
  293.     Set NewTracker = cft
  294. End Function
  295. ' Timer is used to start a series of short
  296. '   tasks, at regular intervals, using one
  297. '   Coffee object (that is, a single thread).
  298. '   Before starting a new task, it checks to
  299. '   see whether the preceding task is done.
  300. ' If you run MTCoffee in the development
  301. '   environment, comment out the code that
  302. '   checks for preceding task completion.
  303. Private Sub tmrShort_Timer()
  304.     Static intCt As Integer
  305.     Static strWaitingFor As String
  306.     Dim cft As CoffeeTracker
  307.     ' If strWaitingFor contains a key, then
  308.     '   the Coffee object is (or was) performing
  309.     '   a task, and the static string variable
  310.     '   contains the key of the CoffeeTracker
  311.     '   that's watching it.
  312.     If strWaitingFor <> "" Then
  313.         On Error Resume Next
  314.         '
  315.         ' If the CoffeeTracker we're waiting
  316.         '   for has dropped out of the
  317.         '   collection, then an error will
  318.         '   occur -- meaning it's time to
  319.         '   start another one.
  320.         Set cft = CoffeeTrackers(strWaitingFor)
  321.         If Err.Number = 0 Then Exit Sub
  322.     Else
  323.         ' If the static string variable is
  324.         '   empty, then the previous series
  325.         '   of short tasks is complete.  A
  326.         '   new series is beginning, so reset
  327.         '   the static counter (intCt).
  328.         intCt = 0
  329.     End If
  330.     If Not CancelAll Then
  331.         intCt = intCt + 1
  332.         '
  333.         ' Create a CoffeeTracker to wait
  334.         '   for the request to finish.
  335.         Set cft = NewTracker(macfe(10).ThreadID, SHORTTASKSIZE)
  336.         '
  337.         ' Give the CoffeeTracker its Coffee
  338.         '   object to watch.
  339.         Set cft.Coffee = macfe(10)
  340.         '
  341.         ' Begin the task.
  342.         Call macfe(10).StartLongTask(SHORTTASKSIZE)
  343.         '
  344.         ' Prepare to wait for the
  345.         '   CoffeeTracker.
  346.         strWaitingFor = cft.ID
  347.     End If
  348.     '
  349.     ' Check to see if we've completed the
  350.     '   series of short tasks, or if we've
  351.     '   been stopped by the Cancel button:
  352.     If (intCt >= mintHowManyShort) Or CancelAll Then
  353.         intCt = 0
  354.         tmrShort.Enabled = False
  355.         strWaitingFor = ""
  356.     End If
  357. End Sub
  358.