[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

VB.NET 2005 - An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll

Posted on 2008-02-06
15
Medium Priority
?
5,268 Views
Last Modified: 2013-11-26
Experts,

While my vb.net windows forms application was running, I got the following runtime error:

-------------------------------------------------------------------------------------------------------------------
An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll
System.StackOverflowException was unhandled
-------------------------------------------------------------------------------------------------------------------

This comes from the attached code snippet. Now, it started happening every few minutes!

Basically, the code reads from a data feed the names of the stocks and their IDs and saves them into an XML file.
Then I read this into a dataset and while I keep receiving prices, I keep searching for their corresponding stock names from this dataset and display them together. That's when I get this error.



Any help is appreciated.
Dim sStockName As String
        Dim iStockID As Integer
        If dsQuotes_Master.Tables.Count > 0 Then
                        sStockName = CType(dsQuotes_Master.Tables(0).Select("row=" & AR(2)), Array)(0)("Stock_E")
                        iStockID = CType(dsQuotes_Master.Tables(0).Select("row=" & AR(2)), Array)(0)("StockID")
        End If

Open in new window

0
Comment
Question by:feesu
  • 7
  • 6
14 Comments
 

Author Comment

by:feesu
ID: 20838704
Experts,

Now, I faced this error in another place. It's in the dataArrival event of the winsock control, where I get the datafeed!
If this means that the feed is too fast or heavy for the application, how come the same control works perfectly with vb6 ?!!

Attached is the code where I faced this error again.

The code broke on the line "Me.Winsock1.GetData(sText)"
  Private Sub Winsock1_DataArrival1(ByVal sender As Object, ByVal e As AxMSWinsockLib.DMSWinsockControlEvents_DataArrivalEvent) Handles Winsock1.DataArrival
        Try
 
            Dim arCR
            Dim sText As String = ""
            Dim Price, Up, Down, AskCnt, AskQty, AskHid, Cross, Qty, QtyL, QtyH, Price1, Price2, Price3, Price4, Price5, Price6, Price7, Price8, Price9, Price10
 
            Me.Winsock1.GetData(sText)
 
            arCR = Split(sText, vbCrLf)
            If Not (Trim(sText) = "" Or UBound(arCR) = 1) Then
 
                For I = 0 To UBound(arCR) - 1
 
                    If (Trim(arCR(0)) <> "") And (Len(arCR(0)) > 1) Then
 
                        arCR(I) = Trim(Mid(Trim(arCR(I)), 1, Len(Trim(arCR(I))) - 2))
                        Me.Text = IIf(bMarketClosed, "Market Closed", "Market Open") & "   -   " & arCR(I)
 
                        AR = Split(arCR(I), "|")
                        If UBound(AR) > 0 Then
 
                            Select Case AR(0)
 
                                Case "$MM"
                                    If AR(3) = 4 Then

Open in new window

0
 
LVL 19

Expert Comment

by:SteveH_UK
ID: 20838768
I don't think the issue is what you think it is.

A stack overflow exception usually occurs because a method triggers a cyclic call pattern, either by calling itself or by generating an event that results in the same event firing again.

The first thing you should do is look at the call stack when the exception is generated.  This should tell you whether the calls are nested.

Can you provide a complete code sample and/or a complete stack trace for the exception?

0
 

Author Comment

by:feesu
ID: 20838804
Hi Steve,

Sure, my scenario is that I use winsock control to receive stock market prices and display them into grids. This winsock used to be use in vb6, and it used to work fine. Today, I needed to make use of vb.net features, but couldnt find that control in .net 2.0 so had to add it manually to my tool box and reference it.

I have got an MDI that has that winsock control that gets triggered with the dataarrival event and from there it spreads the data to the concerned form.

It is important to note that the dataarrival event might be triggered in a fraction of a second. A price may change in less than a second and another type of feed may arrive as well. But didnt expect that this would create such an issue because simply, I still use vb6 to read data and save into the database and it never faced such an error!

I am attaching the code in the MDI/winsock dataarrival event.

 Private Sub Winsock1_DataArrival1(ByVal sender As Object, ByVal e As AxMSWinsockLib.DMSWinsockControlEvents_DataArrivalEvent) Handles Winsock1.DataArrival
        Try
 
            Dim arCR
            Dim sText As String = ""
            Dim Price, Up, Down, AskCnt, AskQty, AskHid, Cross, Qty, QtyL, QtyH, Price1, Price2, Price3, Price4, Price5, Price6, Price7, Price8, Price9, Price10
 
            Me.Winsock1.GetData(sText)
 
            arCR = Split(sText, vbCrLf)
            If Not (Trim(sText) = "" Or UBound(arCR) = 1) Then
 
                For I = 0 To UBound(arCR) - 1
 
                    If (Trim(arCR(0)) <> "") And (Len(arCR(0)) > 1) Then
 
                        arCR(I) = Trim(Mid(Trim(arCR(I)), 1, Len(Trim(arCR(I))) - 2))
                        Me.Text = IIf(bMarketClosed, "Market Closed", "Market Open") & "   -   " & arCR(I)
 
                        AR = Split(arCR(I), "|")
                        If UBound(AR) > 0 Then
 
                            Select Case AR(0)
 
                                Case "$MM"
                                    If AR(3) = 4 Then
                                        bMarketClosed = False
                                    Else
                                        bMarketClosed = True
                                    End If
 
                                Case "$CH"
                                    If AR(11) = 4 Then
                                        bMarketClosed = False
                                    Else
                                        bMarketClosed = True
                                    End If
                                Case "$LL"
                                    ''If dsQuotes_Master.Tables.Count = 1 Then ' to make sure it's not added more than 1 table
                                    'If File.Exists(Me.sXML_Quotes_Master) Then
                                    '    Dim arRows() As DataRow = dsQuotes_Master.Tables(0).Select("ROW=" & Val(AR(2)))
                                    '    If arRows.Length <> 0 Then dsQuotes_Master.Tables(0).Rows.Remove(arRows(0))
                                    'End If
 
                                    'Dim Row1 As DataRow
 
                                    ''Row1 = dtQuotes_Master.NewRow()
                                    'Row1 = dsQuotes_Master.Tables(0).NewRow
 
                                    'Row1("Row") = AR(2)
                                    'Row1("StockID") = AR(3)
                                    'Row1("Stock_E") = AR(4)
                                    'Row1("Stock_A") = AR(5)
 
                                    ''dtQuotes_Master.Rows.Add(Row1)
                                    'dsQuotes_Master.Tables(0).Rows.Add(Row1)
 
                                    ''dsQuotes_Master.Tables.Add(dtQuotes_Master)
                                    'dsQuotes_Master.WriteXml(Me.sXML_Quotes_Master)
                                    ''dsQuotes_Master.Tables.Remove(dtQuotes_Master)
 
                                Case "$TT"
                                    Application.DoEvents()
                                    OnFly_TS.DataArrival(AR)
                                Case "$QQ"
                                    Application.DoEvents()
                                    OnFly_Q.DataArrival(AR)
                                Case "$XX"
                                    Application.DoEvents()
                                    OnFly_Q.DataArrival(AR)
                                Case "$KB"
                                    If bMarketClosed Then Exit Select
                                    OnFly_OB.DataArrival(AR)
                                Case "$KS"
                                    If bMarketClosed Then Exit Select
                                    OnFly_OB.DataArrival(AR)
                            End Select
                        End If
                    End If
                Next
            End If
        Catch ex As Exception
            Me.Text = ex.Message
            'Me.TextBox2.Text = AR(0) & vbCrLf & ex.Message & vbCrLf & vbCrLf & Me.TextBox2.Text
            'MessageBox.Show(ex.Message, "NIC e-360 Streamer", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
 
    End Sub

Open in new window

0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 

Author Comment

by:feesu
ID: 20838825
Hi again,
The stack trace doesn't show details it only displays the following:
error: cannot obtain value

This is the title of the error:
An unhandled exception of type 'System.StackOverflowException' occurred in System.Data.dll

Note that depending on the line the code breaks in, it displays a different dll name in the messge.
0
 
LVL 19

Expert Comment

by:SteveH_UK
ID: 20839172
OK.  Looks like a reentrancy issue.  You don't see this in VB6 because it will run the Winsock control in the same thread as your code, and this means that the Winsock control doesn't fire another event until your code has finished.

In .NET you cannot assume that and so you need to minimise the work that you do inside the event handler and also make sure that the code is thread safe.  This is quite a lot of work to do, I'm afraid.

How much experience do you have of thread-safe programming? Do you know how to use the Monitor class in .NET?

Also, using the Winsock control isn't really a good idea in .NET.  You might find it easier to access the data feed directly.

I'm happy to help you through a code redesign, but it will take a little while...
0
 

Author Comment

by:feesu
ID: 20839193
Steve,

I don't know about thread-safe programming.

I looked up an alternative for winsock in .net but most of the comments I read said to use it by manually add it.

If you have an alternative for the winsock in .net then please tell me, and I think that would solve my issue.

Thanks,
0
 
LVL 19

Expert Comment

by:SteveH_UK
ID: 20840463
Moving away from the Winsock control means using the System.Net and System.Net.Sockets namespaces, depending on exactly what you are trying to do in the Winsock control.

So, my first question is, how are you using the Winsock control?  What are you connecting to and how is it configured?  What are you trying to achieve?
0
 

Author Comment

by:feesu
ID: 20846371
I receive data feed from the stock exchange via TCPIP.

Using winsock was the only way in vb6 to do that.

In winsock, I speicify an IP and a Port. And then call the method "Connect" which triggers the "DataArrival" event.

In that event, I extract the needed data and use it as attached in my code.
0
 
LVL 19

Expert Comment

by:SteveH_UK
ID: 20857121
Have a look here for a good intro to .NET sockets which are the .NET way of using Winsock:
http://msdn.microsoft.com/msdnmag/issues/05/08/HighPerformanceSockets/

See here for the Sockets Reference:
http://msdn2.microsoft.com/en-us/network/bb332030.aspx

You might also want to consider using the TcpClient and UdpClient classes for simpler implementations.

Let me know if you need more assistance, and sorry for the delay getting back to you (work + life = busy!).
0
 

Author Comment

by:feesu
ID: 20860461
Hi Steve,
I have tried the sample code in that article. Entered the IP of the feed host in the text box and the port as well. But it gave an error saying that the host is not available.

In winsock, I only specify the host IP and the port then call Connect method. Can you lead me through the code on how to implement the same? I seem not able to achieve it!

Thanks!
0
 
LVL 19

Expert Comment

by:SteveH_UK
ID: 20860672
Is the server your connecting to a private one?  If not, if you send the details I'll attempt to connect and let you know.  The two most likely issues are (1) that your firewall requires a particular client port number to connect, (2) you are using the wrong protocol (UDP instead of TCP or vice versa).  

I've used the project in the source code (from the link) to connect to Google and view a web page, so it basically works, but it may need to be adapted for your needs.  It works as follows:

1.  It uses Dns.GetHostEntry to lookup IP addresses based on DNS names for both the client and the server
2.  It creates two IPEndPoint objects representing the IP address and port number for the client and the server
3.  It creates a new socket as follows:

  New Socket(myEndpoint.Address.AddressFamily,
                     SocketType.Stream, ProtocolType.Tcp)

The first parameter is indicating that it is an IPv4 or IPv6 address depending on the information it has retrieved about the server.
The second parameter is describing the type of data.  This is important because Tcp and Udp have different default types.  For Udp, you would normally use 'Dgram'.
The final parameter indicates the protocol, in this case Tcp.  It is likely that your solution will need Udp not Tcp.

4.  The Socket.Connect method is called to connect to the specified endpoint, the server.
5.  In the example code, an asynchronous receive pattern is initiated, much like what you are trying to accomplish.  This cycle is started by calling the BeginReceive method.  However, the example code is not attempting to keep on receiving indefinitely so there will be some differences in your code.


So, what code have you produced, is it something you could post?  I'm happy to look over your code for you.
0
 

Author Comment

by:feesu
ID: 20860690
Hi Steve,
First, my feed server is an internal one. I filled in the IP in the text box of the sample application and the port but it gave an error as I mentinoed earlier.

If you think that you can help me with that code, then please consider that I need to specify the host and the port then call the method connect to fire the event "DataArrival" in inside that method, I do my work.

If this is not possible with the code you recommended, then please look at the code I attached. I found on the page: http://www.eggheadcafe.com/articles/20020323.asp

Well, it does the job after specifying the details I mentioned, but I, however, cannot find a way to create that event that fires automatically on receving data! Maybe because I am not an expert in .net and that's where I need your help.

Please try to amend this code I have attached in case you think it is more practical to use it, and help me creating that event I am looking for!


Thanks & Best Regards,,
Imports System.Net.Sockets
Imports System.Text
Class TCPCli
    Shared Sub Main()
 
        Dim tcpClient As New System.Net.Sockets.TcpClient()
        tcpClient.Connect("192.0.3.18", 5555)
        Dim networkStream As NetworkStream = tcpClient.GetStream()
        If networkStream.CanWrite And networkStream.CanRead Then
            ' Do a simple write.
            Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes("Is anybody there")
            networkStream.Write(sendBytes, 0, sendBytes.Length)
            ' Read the NetworkStream into a byte buffer.
            Dim bytes(tcpClient.ReceiveBufferSize) As Byte
            networkStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
            ' Output the data received from the host to the console.
            Dim returndata As String = Encoding.ASCII.GetString(bytes)
            Console.WriteLine(("Host returned: " + returndata))
        Else
            If Not networkStream.CanRead Then
                Console.WriteLine("cannot not write data to this stream")
                tcpClient.Close()
            Else
                If Not networkStream.CanWrite Then
                    Console.WriteLine("cannot read data from this stream")
                    tcpClient.Close()
                End If
            End If
        End If
        ' pause so user can view the console output
        Console.ReadLine()
    End Sub
End Class

Open in new window

0
 
LVL 19

Accepted Solution

by:
SteveH_UK earned 2000 total points
ID: 20891149
Sorry I haven't been able to respond before now.  I was hoping to get a significant amount of time to respond fully, however a project has now begun that is taking all my available time.  I'm aware you have posted a follow-on question and I hope you get a good response from another expert.

The code you have posted gets a Stream for the TCP connection.  The stream can be used to read and write data but it will not notify you of new data arriving.  To do that, you need to use the asynchronous TcpClient.BeginConnect.  You pass in an AsyncCallback delegate and your own state object.  The delegate is similar to using an event.  You just use "AddressOf YourMethod" and you will receive a method call to YourMethod when more data is received by the TcpClient.  However, be careful because the method call will be on a different thread to the one that you call BeginConnect with, so you still need to manage inter-thread communication.  This is in part what the 'state' object is for.  It can be any class derived from Object but should be a reference type (so not Integer, String, etc.).  (String is a reference type but behaves as a value type so should not be used).

Have a look at tutorials on AsyncCallback (do a search in Google) for how to use this.  It will be a more stable solution than using the Winsock control.

I'm afraid I won't be able to comment further on this question.  You can either continue with the other question or post a pointer question to this one.

Whichever way, I do hope my comments have been helpful and you get a solution for your needs.
0
 
LVL 1

Expert Comment

by:Computer101
ID: 21286143
Forced accept.

Computer101
EE Admin
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Native ability to set a user account password via AD GPO was removed because the passwords can be easily decrypted by any authenticated user in the domain. Microsoft recommends LAPS as a replacement and I have written an article that does something …
Planning to migrate your EDB file(s) to a new or an existing Outlook PST file? This video will guide you how to convert EDB file(s) to PST. Besides this, it also describes, how one can easily search any item(s) from multiple folders or mailboxes…
In this video I will demonstrate how to set up Nine, which I now consider the best alternative email app to Touchdown.
Suggested Courses

590 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question