210 likes | 356 Views
Prog 8. More Details Copy and Paste won’t work!. Code Module. Public Enum ReaderWriterType Reader Writer End Enum Public Enum State Wait Start Finish End Enum Public Delegate Sub PassMessage(ByVal theID As String, ByVal theState As State, ByVal Total As Short).
E N D
Prog 8 More Details Copy and Paste won’t work!
Code Module Public Enum ReaderWriterType Reader Writer End Enum Public Enum State Wait Start Finish End Enum Public Delegate Sub PassMessage(ByVal theID As String, ByVal theState As State, ByVal Total As Short)
Interface ‘ Could be an Abstract class Public Interface ReaderWriter WriteOnly Property DisplayMsg() As PassMessage WriteOnly Property mainForm() As Form ReadOnly Property ID() As String ReadOnly Property type() As ReaderWriterType Sub SpinUp() Sub WakeUp() End Interface
Class Reader Public Class Reader ‘ All are private Private readerThread As Thread Private generator As New Random(Now.Second) Private readerEvent As New ManualResetEvent(False) Private _mainForm As Form Private _Message As PassMessage End Class
Class Reader Public Class Reader Implements ReaderWriter ‘ private data ‘ All are private Private WriteOnly Property mainform() As Form Implements ReaderWriter.mainForm Private WriteOnly Property Message() As PassMessage Implements ReaderWriter.DisplayMsg Private Sub WakeUpReader() Implements ReaderWriter.WakeUp Private ReadOnly Property Type() As ReaderWriterType Implements ReaderWriter.type Private Sub StartReader() Implements ReaderWriter.SpinUp Private ReadOnly Property ID() As String Implements ReaderWriter.ID ‘ Thread Sub Private Sub Start() End Class
DB Manager ‘ Could be a class Public Module module1 Private manager As Thread Private managerDone As Boolean ‘ For Readers and Writers Friend managerEvent As New ManualResetEvent(False) ‘ For GUI client to terminate Private endProgram As New ManualResetEvent(False) . . . End Module
Code Module Public Module module1 Friend FIFOQueue As New Queue Friend _total As Short = 100 Friend RC As Integer Friend WC As Integer ‘ To use Monitor on the above variables Friend DataObj As New Object End Module
Monitor on Queue For Readers and Writers Monitor.Enter(FIFOQueue) FIFOQueue.Enqueue(Me) ‘ Wait in the queue ‘ DB manager could be in sleep Monitor.Exit(FIFOQueue) For DB Manager Dim user As ReaderWriter Monitor.Enter(FIFOQueue) user = FIFOQueue.Peek If user.type = ReaderWriterType.Reader Then user = FIFOQueue.Dequeue user.WakeUp() End If Monitor.Exit(FIFOQueue)
Monitor on DB For Readers Monitor.Enter(DataObj) RC -= 1 If RC = 0 Then managerEvent.Set() End If Monitor.Exit(DataObj) For DB Manager Monitor.Enter(FIFOQueue) Monitor.Enter(DataObj) If RC = 0 And WC = 0 And FIFOQueue.Count = 0 Then endProgram.Set() End If Monitor.Exit(DataObj) Monitor.Exit(FIFOQueue)
Communications between Reader/Writer and DB Manager ‘ Manager is not class Friend managerEvent As New ManualResetEvent(False) ‘ Reader/Writer is a class Private readerEvent As New ManualResetEvent(False) ‘ Interface method Private Sub WakeUpReader() Implements ReaderWriter.WakeUp
Communications Between Reader/Writer and DB Manager Friend managerEvent As New ManualResetEvent(False) Private readerEvent As New ManualResetEvent(False) Private Sub WakeUpReader() Implements ReaderWriter.WakeUp ‘ Reader to wait in the queue readerEvent.Reset() managerEvent.Set() readerEvent.WaitOne() ‘ DB manager to wakeup Reader user.WakeUp()
Communications Between Reader/Writer and DB Manager Friend managerEvent As New ManualResetEvent(False) Private readerEvent As New ManualResetEvent(False) Private Sub WakeUpReader() Implements ReaderWriter.WakeUp ‘ DB manager goes to sleep managerEvent.Reset() managerEvent.WaitOne() ‘ Reader/Writer to wake up the manager managerEvent.Set()
Communications Between DB Manager and GUI Client Private manager As Thread Private endProgram As New ManualResetEvent(False) ‘ SpinUp Public Sub startManager() ‘ SpinDown Public Sub endManager() ‘ Finish all readers/Writers in the queue Public Sub FinishReadWrite() Private Sub ManagerToDo()
Terminate DB Manager Private manager As Thread Private managerDone As Boolean Private Sub ManagerToDo() While Not managerDone . . . End While End Sub Public Sub endManager() managerDone = True End Sub
GUI Client ‘ To wait until all readers/writers to finish while ‘ the main thread still handling messages Private endProgThread As Thread Private Sub endProgThreadSub() FinishReadWrite() ‘ Ask user If userAnswer = MsgBoxResult.Yes Then endManager() Application.Exit() End If End Sub Private Sub btnExit_Click(…) Handles btnExit.Click endProgThread = New Thread(AddressOf endProgThreadSub) endProgThread.Start() End Sub
Finishing Readers/Writers Private manager As Thread Private endProgram As New ManualResetEvent(False) Friend managerEvent As New ManualResetEvent(False) Public Sub FinishReadWrite() endProgram.Reset() managerEvent.Set() endProgram.WaitOne() End Sub Private Sub ManagerToDo() While Not managerDone . . . If RC = 0 And WC = 0 And FIFOQueue.Count = 0 Then endProgram.Set() End If End While End Sub
Enable/Disable Buttons ‘ To wait until all readers/writers to finish while ‘ the main thread still handling messages Private endProgThread As Thread Private Sub endProgThreadSub() ‘ Disable buttons FinishReadWrite() ‘ Ask user If userAnswer = MsgBoxResult.Yes Then endManager() Application.Exit() Else ‘ Enbale buttons End If End Sub Will not work! The thread CANNOT access buttons on the form!
Disable Buttons Private Sub btnExit_Click(…) Handles btnExit.Click ‘ Disable buttons is easy endProgThread = New Thread(AddressOf endProgThreadSub) endProgThread.Start() End Sub How to enable buttons? Thread endProgThread knows when to enable buttons. But cannot access the buttons. How to tell the main thread to enable the buttons?
Use Delegate ‘ On the form Private Delegate Sub EnableButtons() Dim doit As EnableButtons Private Sub Form1_Load(. . .) Handles MyBase.Load startManager() Me.doit = AddressOf HandleRestart End Sub Sub HandleRestart() 'Handles Me.Restart btnNewReader.Enabled = True btnNewWriter.Enabled = True btnExit.Enabled = True End Sub
Enable Buttons Private endProgThread As Thread Private Sub endProgThreadSub() ‘ Buttons are disabled by the main thread FinishReadWrite() ‘ Ask user If userAnswer = MsgBoxResult.Yes Then endManager() Application.Exit() Else ‘ Tell the main thread to enbale buttons Me.Invoke(doit) End If End Sub
Prog 8 Copy and Paste won’t work!