|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Thread Sync Queue Problemfor error logging. Consider the following code: <code> SyncLock _eventList.SyncRoot Dim item As ExceptionLogEntry ' If there are items, get the top one If _eventList.Count > 0 Then ' Get the item from the queue item = CType(_eventList.Dequeue, _ ExceptionLogEntry) ' If we got an item to log, log it If Not item Is Nothing Then WriteToLog(BuildExceptionReport(item)) End If End If End SyncLock </code> This method is running as a new thread, created thus: <code> _thread = New Thread(AddressOf StartWatching) _thread.Start() </code> FACTS: 1) The _thread is System.Threading.Thread, the _eventList is System.Collections.Queue, both are member variables of the class. 2) The class this code appears in could have more than one instances (hence using threading). 3) I'm using .NET 1.1. 4) The _eventList object is referenced by the producer class (not listed here), where Enqueue is called inside a SyncLock block. MY PROBLEM: Thing is, it seems that "_eventList.count > 0" returns true, and still is just before the dequeue call, but after the dequeue call it goes to 0, and "item" is NOTHING!! I have no idea why this could be. Can anyone help!?! Cheers, <Shipcreak /> Full class follows: Imports System.Text Imports System.Threading Public MustInherit Class LoggerBase Private _name As String Private _eventList As Queue Private _thread As Thread Private _stopRequested As Boolean Public Sub New(ByVal pName As String) _name = pName End Sub Public Sub AssignEventList(ByVal eventList As Queue) If Not _eventList Is Nothing Then SyncLock _eventList _eventList = eventList End SyncLock Else _eventList = eventList End If End Sub Public Sub Start() _stopRequested = False _thread = New Thread(AddressOf StartWatching) If Not _name Is Nothing AndAlso _name.Length > 0 Then _thread.Name = _name Else _thread.Name = "Event Logging Thread" End If _thread.Start() End Sub Public Sub RequestStop() _stopRequested = True End Sub Private Sub StartWatching() While Not _stopRequested ' Lock the list SyncLock _eventList.SyncRoot Dim item As ExceptionLogEntry ' If there are items, get the top one If _eventList.Count > 0 Then ' Get the item from the queue item = CType(_eventList.Dequeue, ExceptionLogEntry) ' If we got an item to log, log it If Not item Is Nothing Then WriteToLog(BuildExceptionReport(item)) End If End If End SyncLock ' Wait for 1 sec to allow other threads to take their turn Thread.CurrentThread.Sleep(100) End While End Sub Private Function BuildExceptionReport( _ ByVal ex As ExceptionLogEntry) As String Dim ret As New StringBuilder Dim e As ExceptionLogEntry = ex If Not e Is Nothing Then ret.AppendFormat("OS: {0}" & vbCrLf, ex.OSInfo) ret.AppendFormat("Processor usage: {0}" & vbCrLf, _ ex.ProcessorUsage) ret.AppendFormat("Working Set: {0}" & vbCrLf, _ ex.WorkingSet) ret.AppendFormat("Free Memory: {0}" & vbCrLf, _ ex.FreeMemory) ret.AppendFormat("OS UserName: {0}" & vbCrLf, _ ex.OSUserName) ret.AppendFormat("Machine Name: {0}" & vbCrLf, _ ex.MachineName) 'ret.AppendFormat("Total HDD: {0}" & vbCrLf, _ ex.HDDTotal) 'ret.AppendFormat("Free HDD: {0}" & vbCrLf, _ ex.FreeHDD) ret.AppendFormat("Occurred At: {0}" & vbCrLf, _ ex.Occurred) ret.Append("Exception details:" & vbCrLf) AppendExceptionDetails(ex.CausingException, ret) WriteToLog(ret.ToString) Else WriteToLog("No exception data provided") End If End Function Private Sub AppendExceptionDetails(ByVal ex As Exception, _ ByVal report As StringBuilder) Dim e As Exception = e Do While Not e Is Nothing report.AppendFormat(" Message: {0}" & vbCrLf, _ e.Message) report.AppendFormat(" Source: {0}" & vbCrLf, _ e.Source) report.AppendFormat(" Method: {0}" & vbCrLf, _ e.TargetSite.Name) report.AppendFormat(" Help Link: {0}" & vbCrLf, _ e.HelpLink) report.AppendFormat(" Stack Trace: {0}" & vbCrLf, _ e.StackTrace) report.Append("------------------" & vbCrLf) e = e.InnerException Loop End Sub Protected MustOverride Sub WriteToLog(ByVal item As String) Protected MustOverride Sub WriteToLog(ByVal item As String, _ ByVal type As EventLogEntryType) End Class shipcr***@gmail.com wrote:
Show quoteHide quote > I have an interesting problem with a sort of producer-consumer system In my not-particularly-expert opinion, this looks OK.> for error logging. Consider the following code: > > <code> > SyncLock _eventList.SyncRoot > > Dim item As ExceptionLogEntry > > ' If there are items, get the top one > If _eventList.Count > 0 Then > > ' Get the item from the queue > item = CType(_eventList.Dequeue, _ > ExceptionLogEntry) > > ' If we got an item to log, log it > If Not item Is Nothing Then > > WriteToLog(BuildExceptionReport(item)) > > End If > > End If > > End SyncLock > </code> [snip] > 4) The _eventList object is referenced by the producer class (not I think you're going to have to have a look at the enqueueing code, and> listed here), where Enqueue is called inside a SyncLock block. > > MY PROBLEM: > Thing is, it seems that "_eventList.count > 0" returns true, and still > is just before the dequeue call, but after the dequeue call it goes to > 0, and "item" is NOTHING!! > > I have no idea why this could be. Can anyone help!?! if you can't find the problem, post some of it. The key point which you may need reminding of (from the docs, my emphasis): Queue.Enqueue Method Adds an object to the end of the Queue. Public Overridable Sub Enqueue( _ ByVal obj As Object _ ) Parameters obj The object to add to the Queue. ****The value can be a null reference (Nothing in Visual Basic). **** My example code: Sub Main() Dim q As New Queue q.Enqueue("apple") q.Enqueue("banana") q.Enqueue(Nothing) q.Enqueue("pear") Dim o As Object Do While q.Count > 0 o = q.Dequeue ' everything implements ToString, right? Console.WriteLine(o.ToString) ' OOPS Loop Console.ReadLine() End Sub -- Larry Lard Replies to group please Yeah, you're right. I worked out what it was yesterday afternoon
eventually. I was adding the result of a call to a factory class method to the queue, but the factory was returning Nothing. Put null in, get null out. Simple. Thanks for the reply, one's never guaranteed one in here, so many people with so many problems an' all that. :-) <Shipcreak />
Fat client - Server: Which technology?
Alternative to OpenFileDialog? umanaged code - array error Outlook Add In is not shown for 1 user... Regular expression rejecting invalid files Serial Port - How To Use "Invoke" On The Second Thread licensing a third party control UBound behaviour Option Strict On does not cause compilation error Ignoring mouse event from contained controls |
|||||||||||||||||||||||