Could not write in a closed textWriter, but it was opened !
Hello,
I have made an application that saves data incoming from a serialPort to a *.txt file.
I have basically one button that launchs the whole process.
serialPort connection
name or select a file to write in
create a new streamWriter
write a line "first line" to the text file
receive all the data and store them in the text file
close the stream writer
close the serial connection
My application works well when I first launch it. I get the data, save them in the text File, close the streamWriter and disconnect the serial port. The problem comes when I click a second time on the main button, then it should follow the same process a second time, but it seems that the application doesn't want to write to the text file a second time.
Here are the most relevant things :
Public Class Export
Private _fileName As String
Private _objStream As System.IO.StreamWriter
Public Sub Go()
Main.SaveFileDialog1.ShowDialog() 'name or select a file to write in
_fileName = Main.SaveFileDialog1.FileName
'If _fileName <> "" Then process
_objStream = New System.IO.StreamWriter(_fileName, True) 'create a new streamWriter
'writting in the first line
_objStream.WriteLine("first Line")
'getting the data
'writing the data to the text file in a loop <-- crash here at the second run
End Sub
I connect the serial port before creating a thread that launch the go function adn close it after.
As I said when I fisrt launch the function everything goes well, when I launch the new thread a second time, I get an error while writing the data to the text file in a loop. But it did go well for the first line writing !
It is an ObjectDisposedException "impossible to write in a closed TextWriter".. any guess to go around this problem ?
Thank you in advance
It would help if you showed us the actual code that causes the error because there's obviously something wrong with it but we can only guess at what that might be without seeing the code. I'm guessing that you are using the original StreamWriter rather than the new one. As I said though, that's just a guess.
Also, are you actually using the _fileName and _objStream variables outside the Go method? If not then why are they declared outside the Go method? If you are creating, using and destroying a disposable object like a StreamWriter within the same method then the proper way to do so is like this:
Using writer As New IO.StreamWriter(filePath)
'Use writer here.
End Using
The Using block declares the variable, defines its own scope and implicitly disposes the object.
Thank you for your answer, I tried to simplify my problem as much as I could but if you want the full code, then I'll show it up. I do use _fileName and _objStream variables outside the Go method. As you said I am probably using the firstly created StreamWriter, even if I am creating a new one.
Public Class Export Private _fileName As String
Private _objStream As System.IO.StreamWriter
Private _radioGPX As Boolean
Public Event FinishedExporting(ByVal thisThread As System.Threading.Thread)
Dim theForm As Main = CType(My.Application.OpenForms("Main"), Main)
Sub New(ByVal RadioGPX As Boolean)
_radioGPX = RadioGPX
AddHandler theForm.FinishedReceiving, AddressOf FinishedReceivingEventHandler
End Sub
Public Sub Go()
If _radioGPX = True Then
Main.SaveFileDialog1.FileName = "file.gpx"
Main.SaveFileDialog1.Filter = "GPX File (*.gpx)|"
Else
Main.SaveFileDialog1.FileName = "file.txt"
Main.SaveFileDialog1.Filter = "Text File (*.txt)|"
End If
_objStream = New System.IO.StreamWriter(_fileName, True) '<-------- creating a new StreamWriter
If _radioGPX = True Then
prepareTextGPX(True) '<--------- writing the begining of the GPX file, this worked without errors even on the second launch
End If
theForm.sendA(Nothing) 'send a "a" and wait for the FinishedReceiving event raised by another thread
Else
RaiseEvent FinishedExporting(System.Threading.Thread.CurrentThread)
MsgBox("Please select a valid directory", MsgBoxStyle.Exclamation, "Error")
End If
End Sub
Public Sub writeTXT(ByVal pq As Paquet, ByRef type As String)
If type = "txt" Then
_objStream.WriteLine(pq.getPaquet) '<----- this is where I get the error on the second run in a raw
ElseIf type = "gpx" Then
_objStream.WriteLine(pq.getPaquetGpx)
End If
'MsgBox("Text Appended to the File")
End Sub
Public Sub prepareTextGPX(ByVal debut As Boolean)
If debut Then
_objStream.WriteLine("<?xml blabal?>") '<-- this worked without errors even on the second launch
Else
_objStream.WriteLine(vbTab + vbTab + "</blabla>")
End If
End Sub
Sub FinishedReceivingEventHandler()
Dim paquetList() As String
Dim paquet_1 As Paquet
If theForm._mainString <> Nothing Then
Dim i As Integer = 0
paquetList = theForm._mainString.Split(";"c)
For Each s As String In paquetList
If (s.Length = 36) Then
If (StrComp(s.Substring(18, 18), "ffffffffffffffffff") <> 0) Then
paquet_1 = New Paquet(s)
If Not paquet_1.getError Then
If _radioGPX = True Then
writeTXT(paquet_1, "gpx")
Else
writeTXT(paquet_1, "txt")
End If
theForm.SetText(vbCrLf + i.ToString + " " + paquet_1.getPaquet)
i += 1
End If
End If
End If
Next
End If
If _radioGPX = True Then
prepareTextGPX(False) 'writting the end of the GPX file
End If
_objStream.Close() 'closing the stream
RaiseEvent FinishedExporting(System.Threading.Thread.CurrentThread)
End Sub
End Class[COLOR=#3E3E3E][/COLOR]
and here is how the go function is executed creating a new thread from the Main:
Private Sub BtGo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtGo.Click
Connect()
If SerialPort1.IsOpen Then
BtGo.Enabled = False
_mainString = "" 'reset of the receiving string
Dim Export1 As New Export(RadioGPX.Checked)
Dim thread1 As New System.Threading.Thread(AddressOf Export1.Go)
thread1.SetApartmentState(Threading.ApartmentState.STA)
AddHandler Export1.FinishedExporting, AddressOf FinishedExportingEventHandler
setSpinnerVisible(True)
thread1.Start()
Else
MsgBox("Serial Port not connected", MsgBoxStyle.Critical, "Error")
End If
End Sub[COLOR=#3E3E3E][/COLOR]
I'm guessing that you have one thread trying to write to the StreamWriter after another thread has closed it. I'd maybe put a breakpoint on the line(s) that closes the StreamWriter so that you can detect exactly when it's executed and you will likely find that it's not when you expect. Alternatively, put a Debug.WriteLine after every use of the StreamWriter so that you can see the exact sequence of events.
Hello,
I have added some debug writelines and tracked what happened. As I said before, there is no way for the stream to be closed before the end of the process I only have one line to close the Stream, and it wasn't called, there must be some kind of trouble with the threads.. but how / why ?
Code:
_filename :C:\Users\Blabla\Desktop\text.gpx
writting prepare
Send A
Le thread '<Sans nom>' (0x17b8) s'est arrêté avec le code 0 (0x0).
Finished Receiving Raised
Finished Receiving
mainstring :00010202040106070457f8e80200f1340200;ce6bb3024ea12e5f0457f8e80200f7340200;ce6bb3024ea12e5f0457f8e80200ff340200;ce6bb3024ea12e5f0457f8e8020008350200;ce6bb3024ea12e5f0457f8e8020010350200;ce6bb3024ea12e5f0457f8e8020041350200;ce6bb3024ea12e5f0457f8e8020049350200;4a6cb3024e3a2e5f0457f8e8020051350200;4d6cb3024e362e5f0457586201005a350200;4d6cb3024e362e5f04575862010062350200;4d6cb3024e362e5f0457586201006a350200;4d6cb3024e362e5f04575862010073350200;4d6cb3024e362e5f045758620100a3350200;ffffffffffffffffffffffffffffffffffff;ffffffffffffffffffffffffffffffffffff;ffffffffffffffffffffffffffffffffffff;ffffffffffffffffffffffffffffffffffff;ffffffffffffffffffffffffffffffffffff;ffffffffffffffffffffffffffffffffffff
Writting
Writting
Writting
...
Writting
Writting
Writting
Writting
writting prepare
closing _objstream
Le thread '<Sans nom>' (0xfb0) s'est arrêté avec le code 0 (0x0).
Le thread '<Sans nom>' (0x1b2c) s'est arrêté avec le code 0 (0x0).
Le thread '<Sans nom>' (0x1200) s'est arrêté avec le code 0 (0x0).
Le thread '<Sans nom>' (0xd94) s'est arrêté avec le code 0 (0x0).
Le thread '<Sans nom>' (0x11e0) s'est arrêté avec le code 0 (0x0).
Le thread '<Sans nom>' (0x12cc) s'est arrêté avec le code 0 (0x0).
Le thread '<Sans nom>' (0x17a8) s'est arrêté avec le code 0 (0x0).
_filename :C:\Users\Blabla\Desktop\test2.gpx <-------------------------------------- launch it a second time
writting prepare<-------------------------------Writes
Send A
Le thread '<Sans nom>' (0x1b48) s'est arrêté avec le code 0 (0x0).
Finished Receiving Raised
Finished Receiving
mainstring :00010202040106070457f8e80200f1340200;ce6bb3024ea12e5f0457f8e80200f7340200;ce6bb3024ea12e5f0457f8e80200ff340200;ce6bb3024ea12e5f0457f8e8020008350200;ce6bb3024ea12e5f0457f8e8020010350200;ce6bb3024ea12e5f0457f8e8020041350200;ce6bb3024ea12e5f0457f8e8020049350200;4a6cb3024e3a2e5f0457f8e8020051350200;4d6cb3024e362e5f0457586201005a350200;4d6cb3024e362e5f04575862010062350200;4d6cb3024e362e5f0457586201006a350200;4d6cb3024e362e5f04575862010073350200;4d6cb3024e362e5f045758620100a3350200;ffffffffffffffffffffffffffffffffffff;ffffffffffffffffffffffffffffffffffff;ffffffffffffffffffffffffffffffffffff;ffffffffffff...
'VB.net 2005 Simple CDC Demo.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_fr_b77a5c561934e089\mscorlib.resources.dll' chargé
Une exception de première chance de type 'System.ObjectDisposedException' s'est produite dans mscorlib.dll
I have understood that the problem comes from the fact that the thread1 seems not to be closed totaly and the _objStream wants to be reused.. I have no idea how to go around this problem.
I have detected the problem while using the code you gave me
Using writer As New IO.StreamWriter(filePath)
'Use writer here.
End Using
I did not have the problem again however when I was writing to a file:
- it writes to file1
when I then asked to write in file2 it
- writes in file2
- AND !! writes in file1 !!
This means that the thread1 seems to still be running !! and a new thread1_copy has been opened !
Bookmarks