Hi,
I have a multithreaded application that crashes with the following msg in event log ...
EventType clr20r3, P1
smartserver2005.exe, P2 1.0.0.0, P3 43f6cc52, P4 system, P5 2.0.0.0, P6
4333ae87, P7 3ad8, P8 a5, P9 system.objectdisposedexception, P10
NIL.
I have provided try catch block in all routines in
the code & still the appl crashes with the above msg. Note that
crash is not consistent for a particular sequence of events.
Any suggestions
-S.Malathi

system.objectdisposedexception
jnickfl1
Thanks for the assistance.
I don't think that I missed sthg with Close/Dispose/Using - I've gone thro' the code.
Had an observation today ...
Instead of having 4 threads, I limited to 2 threads & the appl could pick up 10 calls. This never happened when I had 4 threads.
Any point to be considered while threading SerialPort
-S.Malathi
Aron789
The threads are self contained.
No obj is referenced from across the threads.
This code was migrated from .NET 2003 where I didn't have this pblm.
I'll double chk my code if any obj could get disposed.
Any further suggestions
-S.Malathi
mghile
Think about this situation: you making a BeginInvoke() call on some delegate while object is valid, then you call Close/Dispose or something that make it. When thread pool accept delegate to execute, it may receive disposed object. In this case you can't handle exception and get results you have. I think it's possible.
Anyway you should check all your Dispose, Close and using() in your app. I'm sure one of them making you problem.
bmcneill0
Hi!
I think your problem happens in SampleReceiveData() - add try-catch block there to see it you can trap error.
P. S. You can pass params easier to the thread by using parametrized start routine and Thread.Start(parameter). Check MSDN for details.
DeanHuff
I check MSDN about SerialPort. Here what I found there:
1. events called on worker thread, so you can't call MessageBox() and form's method without BeginInvoke()
2. events may be called out of order, but one at a time (it's not clear one event of any kind or same kind at a time). So you may receive them in reverse order too.
I suggest you to use System.Diagnostrics.Trace.WriteLine() and attach a trace listener (see about TraceListener class in MSDN), so you can log all internal events into log file and get better understanding of internal processes. You can trace all objects you have, so you can detect which one is disposed.
P.S. You can also trace when Disposed event raised on SerialPort itself to see that when it was disposed.
Ketema Harris
Hi!
It appears that one of your threads Dispose() some object and another reference this object later. Disposing doesn't mean object references will become null. Check MSDN for Dispose() patterns.
mathieu.szablowski
You are calling f_frmSmartServer.LogMsg1 from your worker threads, which in turn is accessing txtLog, presumably a Control (TextBox) on a Windows Form.
This is illegal: you should be using Control.Invoke to execute on the form's thread.
Also I don't see where you shut down your worker threads before closing the form. If you don't do this the worker threads could continue to call LogMsg1 after the form is closed, which will give an ObjectDisposedException.
PeteL - MSFT
Added try catch as well.
Worker threads are not shut down in this sample. However the crash occurs even 'fore the form is closed.
Still I get the same crash & msg in event viewer.
Instead of threading, I instantiated the class as an object in the main form and communicated successfully in that thread.
Has anyone threaded SerialPort communication
Any further suggestions
Imports System.IO.Ports
Public Class MSSerialPortTest
Private WithEvents _SaxSerialConn As New SerialPort
Dim _PortNo As Integer
Public Sub New(ByVal PortNo As Integer, ByVal bps As Integer, ByVal DataBits As Byte, ByVal Serial As Boolean, ByVal GridRowID As Integer)
Try
_PortNo = PortNo
_SaxSerialConn = New SerialPort("COM" & _PortNo, bps, Parity.None, DataBits, StopBits.One)
_SaxSerialConn.DtrEnable = True
_SaxSerialConn.RtsEnable = True
_SaxSerialConn.Open()
Catch ex As Exception
MessageBox.Show(ex.ToString, "New", MessageBoxButtons.OK)
'f_frmSmartServer.LogMsg1("New-" & ex.ToString)
End Try
End Sub
Private Sub _SaxSerialConn_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles _SaxSerialConn.DataReceived
Try
SampleReceiveData()
Catch ex As Exception
MessageBox.Show(ex.ToString, "_SaxSerialConn_DataReceived", MessageBoxButtons.OK)
'f_frmSmartServer.LogMsg1("_SaxSerialConn_DataReceived-" & ex.ToString)
End Try
End Sub
Private Sub SampleReceiveData()
Dim Data As String
Try
Data = _SaxSerialConn.ReadExisting
'f_frmSmartServer.LogMsg1("Data: " & Data)
If InStr(Data, "RING") > 0 Then
_SaxSerialConn.Write("ATA" & Chr(13))
End If
If InStr(Data, "CONNECT") > 0 Then
_SaxSerialConn.Write(Chr(5))
End If
If InStr(Data, "1000600100200") > 0 Then
_SaxSerialConn.Write(Chr(6))
End If
Catch ex As Exception
MessageBox.Show(ex.ToString, "SampleReceiveData", MessageBoxButtons.OK)
'f_frmSmartServer.LogMsg1("SampleReceiveData-" & ex.ToString)
End Try
End Sub
Private Sub _SaxSerialConn_ErrorReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialErrorReceivedEventArgs) Handles _SaxSerialConn.ErrorReceived
MsgBox(e.EventType.ToString)
End Sub
End Class
Michael Adamson
How many Dispose(), Close() and using statements you have You should check them all, hope they less than hundred
.
lax4u
It will be tough to see why you are getting the exception
without looking into the code. If a thread pool thread gets the exception,
the application can end without invoking the catch block.
Please post your code and we can see what is going on
sriesch
Why should the appl crash even if there is a code accessing a disposed obj This should be handled in the catch block but not crash.
-S.Malathi
soellnas
You might be able to repro this issue with simpler code.
In any case the object disposed exception can be easily caught by looking at what
objetc we are talkking about and placing some tracing calls.
Also the system.Net trace log file should help. In case you have not already visited my blog, take a look at http://blogs.msdn.com/dgorti
*David*
But unfortunately I wouldn't be able to do that. The code is very huge and I have security concerns as well.
I got a bit drifted to sthg else today morning. Need to get back & chk what could be done further.
nmanville
I have reproduced the code in simpe terms. Even this crashes...
'********** f_frmSmartServer contains ***********
Dim SaxThread(10) As System.Threading.Thread
Private Sub StartSmartServer()
Try
SaxThread(0) = New System.Threading.Thread(AddressOf SetConfig)
SaxThread(0).Name = Format(6, "00") & "-" & 6
SaxThread(0).Start()
SaxThread(1) = New System.Threading.Thread(AddressOf SetConfig)
SaxThread(1).Name = Format(15, "00") & "-" & 15
SaxThread(1).Start()
Catch ex As Exception
MessageBox.Show(ex.ToString, "StartSmartServer", MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)
End Try
End Sub
Private Sub SetConfig()
Dim SSConn As MSSerialPortTest, PortNo As Integer, GridID As Integer
Dim ThreadName As String = System.Threading.Thread.CurrentThread.Name
Try
PortNo = Mid(ThreadName, 4, Len(ThreadName) - 3)
GridID = CInt(Mid(ThreadName, 1, 2))
SSConn = New MSSerialPortTest(PortNo, 19200, 8, SSSettings.Communication.Serial, GridID)
Catch ex As Exception
MessageBox.Show(ex.ToString, "SetConfig", MessageBoxButtons.OK, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly)
End Try
End Sub
Public Sub LogMsg1(ByVal Msg As String)
Try
txtLog.Text = txtLog.Text & vbCrLf & Msg
txtLog.SelectionStart = Len(txtLog.Text) - 1
txtLog.ScrollToCaret()
Catch ex As Exception
'Console.WriteLine("LogMsg1" & ex.ToString)
End Try
End Sub
'****************** CLASS to be threaded **************
Imports System.IO.Ports
Public Class MSSerialPortTest
Private WithEvents _SaxSerialConn As New SerialPort
Public Sub New(ByVal PortNo As Integer, ByVal bps As Integer, ByVal DataBits As Byte, ByVal Serial As Boolean, ByVal GridRowID As Integer)
_SaxSerialConn = New SerialPort("COM" & PortNo, bps, Parity.None, DataBits, StopBits.One)
_SaxSerialConn.DtrEnable = True
_SaxSerialConn.RtsEnable = True
_SaxSerialConn.Open()
End Sub
Private Sub _SaxSerialConn_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles _SaxSerialConn.DataReceived
SampleReceiveData()
End Sub
Private Sub SampleReceiveData()
Dim Data As String
Data = _SaxSerialConn.ReadExisting
f_frmSmartServer.LogMsg1("Data: " & Data)
If InStr(Data, "RING") > 0 Then
_SaxSerialConn.Write("ATA" & Chr(13))
End If
If InStr(Data, "CONNECT") > 0 Then
_SaxSerialConn.Write(Chr(5))
End If
If InStr(Data, "1000600100200") > 0 Then
_SaxSerialConn.Write(Chr(6))
End If
End Sub
End Class