I made a windows service that listens to a port(using HttpListner) and accepts XML Repuest and once the request is valid it connects to a database (usually on the same pc) and construct the xml response and sends it back.
So far, Everything is great except when the service accepts two or more requests that require retrieving 100+ records, it crashes. First, I was using just one shared connection to the database, it does crashes, then I changed to multiple connections i.e. when you need something from the database create your connection.
I did some troubleshooting using eventlog to get the exceptions, here are some of the exception I got before crashing:
A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)
The ConnectionString property has not been initialized.
ExecuteReader requires an open and available Connection. The connection's current state is connecting.
ExecuteReader requires an open and available Connection. The connection's current state is open.
Invalid attempt to call Read when reader is closed.
Here is a sample of the code I am using:
Private Sub StartLisitng()
MyListener.Start()
Dim result As IAsyncResult
result = MyListener.BeginGetContext(New AsyncCallback(AddressOf ListnerCallback), MyListener)
End Sub
Private Sub ListnerCallback(ByVal result As IAsyncResult)
StartLisitng()
If result.IsCompleted Then
ctx = MyListener.EndGetContext(result)
Dim HandleRequestThread As New Thread(AddressOf New HandleRequest(ctx).RequestProcess)
HandleRequestThread.Start()
End If
End Sub
Public Function RemoteConnect(ByVal DNSBranch As String) As Boolean
Dim IsRemoteConnected As Boolean = False
RemoteConnString = "Data Source = " & DNSBranch & ";Initial Catalog=xxxxx;User ID=xxxxx;Password=xxxxx;Connect Timeout=5;MultipleActiveResultSets=True;"
RemoteConn = New SqlConnection(RemoteConnString)
Try
RemoteConn.Open()
Catch ex As Exception
IsRemoteConnected = False
End Try
If RemoteConn.State = 1 Then
IsRemoteConnected = True
Else
IsRemoteConnected = False
End If
Return IsRemoteConnected
End Function
Public Function RemoteExeComd(ByVal DNSBranch As String, ByVal query As String) As DataSet
Dim MyDataSet As New DataSet
RemoteConnect(DNSBranch)
Comd = New SqlCommand(query, RemoteConn)
Adapter = New SqlDataAdapter(Comd)
If query.StartsWith("Se") Or query.StartsWith("se") Or query.StartsWith("SE") Then
If RemoteConn.State = ConnectionState.Open Then
Try
Adapter.Fill(MyDataSet)
Catch ex As Exception
EventLog.WriteEntry("My Service", "Exception: " & ex.Message.ToString)
End Try
End If
Else
Try
Comd.ExecuteNonQuery()
Catch ex As Exception
EventLog.WriteEntry("My Service", "Exception: " & ex.Message.ToString)
End Try
End If
Comd.Dispose()
Adapter.Dispose()
Return MyDataSet
End Function
I do not have any problems with the listner or parsing the request, I know I have the problem on how i interact with the databse.
Any advice, Thanks for you time.
Related
I'm using the following code to open a database connection. If the connection fails for any reason, I get the typical VB error message with all of the details. and my program stops. It does not give me my graceful message and ending.
My try/catch does not work regardless of the connection error (whether it is password related, network related, or sql server related).
I need my program to continue on even if I can't connect to the database.
Public Class SQL_Connection
Public conn As New SqlConnection
Public cmd As New SqlCommand
Public Sub New()
conn.ConnectionString = my_connection_string
Try
conn.Open()
Catch ex As Exception
MessageBox.Show("Unable to open database. " + ex.ToString)
End Try
cmd = conn.CreateCommand()
End If
End Sub
End Class
Have a look at this article.
If the program is not run in debug mode, the try catch would do it's thing right away with out stopping the execution.
I am working on created a login form for an application I am working on. I have my application set up to properly connect to the database and run stored procedures and queries on the database as well.
However I am unsure how to send messages from the database to my VB.Net Application. Right now I have essentially two methods that execute code for my database:
Public Function ExecuteCMD(ByRef CMD As SqlCommand) As DataTable
Dim DS As New DataSet()
Try
OpenDBConnection()
CMD.Connection = DB_CONNECTION
If CMD.CommandText.Contains(" ") Then
CMD.CommandType = CommandType.Text
Else
CMD.CommandType = CommandType.StoredProcedure
End If
Dim adapter As New SqlDataAdapter(CMD)
adapter.SelectCommand.CommandTimeout = 300
adapter.Fill(DS)
Catch ex As Exception
Throw New Exception("Database Error: " & ex.Message)
Finally
CloseDBConnection()
End Try
Return DS.Tables(0)
End Function
Public Function ExecuteCMDWithReturnValue(ByRef CMD As SqlCommand) As Boolean
Try
OpenDBConnection()
CMD.Connection = DB_CONNECTION
CMD.Parameters.Add("#ret", SqlDbType.Int).Direction = ParameterDirection.ReturnValue
CMD.CommandType = CommandType.StoredProcedure
CMD.ExecuteNonQuery()
Dim result As Object = CMD.Parameters("#ret").Value
Return If(Convert.ToInt32(result) = 1, False, True)
Catch ex As Exception
Throw New Exception("Database Error: " & ex.Message)
Return False
Finally
CloseDBConnection()
End Try
End Function
These functions honestly work fine, but they are horrible for error processing.
For example I'd like to be able to set up my Store Procedure for logging in to the application to return a "Username not found" or "Password incorrect" message so that I can display to my user exactly what the problem is, as opposed to just returning a generic "Login information incorrect" message from only returning true or false on the logging in going through or not.
I unfortunately do not know exactly how to do this on either end. I don't know what to set up on the SQL Server side to have it spit out messages in procedures, and I don't know hot to receive those messages in VB.Net.
You can verify your user right in VB. I don't think it is a good idea to tell the user If the password or user name is wrong (or if both are wrong). If this data is password protected then it should be protected from malicious logins. It would help a hacker to know what was wrong.
Private Function VerifyPassword(pword As String, uname As String) As Boolean
Using cn As New SqlConnection(My.Settings.UsersConnectionString)
Dim cmd As New SqlCommand("Select Count(*) From Users Where UserName = #UserName And UserPassword = #Password;", cn)
cmd.Parameters.Add("#UserName", SqlDbType.VarChar, 100).Value = uname
cmd.Parameters.Add("#Password", SqlDbType.VarChar, 100).Value = pword
Try
cn.Open()
Dim i As Integer = CInt(cmd.ExecuteScalar())
If i > 0 Then Return True
Return False
Catch ex As Exception
Throw
Finally
cn.Close()
cmd.Dispose()
End Try
End Using
End Function
Of course the password is stored hashed with a salt.
I'm using VB.NET to create a simple application which will test if a variety of SQL Server are available online.
I have the code below, but the timeout is not working and it simply waits forever rather than throwing a timeout error. I have put breakpoints in and, as this is in an loop of IP's, it never progresses if the IP being checked is unavailable.
Dim data As New SqlClient.SqlConnection("Data Source=DatabaseIP;Initial Catalog=POS;Integrated Security=False;User ID=sa;Password=;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False".Replace("DatabaseIP", IP))
Try
data.Open()
Catch ex As Exception
Dim stophere As String = ""
TextBox1.Text += IP + vbNewLine
End Try
Connect Timeout=15 is not correct, try it with Connection Timeout=15
To connect with Database, following code is enough,
Dim data As New SqlClient.SqlConnection("Data Source=DatabaseIP;Initial Catalog=POS;Integrated Security=False;User ID=sa;Password=;")
I have developed winform application using VB.NET. The application is deployed in the machine which is connected to wireless network. The machine is in the car(moving object).
The application has DataGridView loaded with the data get from MSSQL Server(in Remote machine). The data is refreshed for every 5 seconds.
I have used the NetworkAvailabilityChanged event to detect the network status. If the Network is available, then I retrieve the data from the table.
Code:
AddHandler NetworkChange.NetworkAvailabilityChanged, AddressOf NetworkStateChangeHandler
Public Sub NetworkStateChangeHandler(ByVal sender As Object,
ByVal e As NetworkAvailabilityEventArgs)
If e.IsAvailable = True Then
g_bNetworkAlive = True
Else
g_bNetworkAlive = False
End If
End Sub
private Sub GetData()
If g_bNetworkAlive = True
'code to get the data from table
End If
End Sub
Issue:
If the car movers out of the out of the network, the NetworkAvailabilityChanged event is not fired. so it throws the following error for every 5 seconds and application gets crashed.
A network-related or instance-specific error occurred while establishing
a connection to SQL Server. The server was not found or was not accessible.
Temporary fix: I have made Ping request to the SQL server machine for every 5 seconds to detect the network status. It affects the application's performance.
Note: If I manually switch off the Wifi, the NetworkAvailabilityChanged event is fired. The issue is only when the car moves out of the network.
Is there any some other feasible solution to detect the wireless network status?
Indeed there is.
Why send http request to some dummy website when you can check if you are connected to wifi or not locally.
Use ManagedWifi APIs, This will eliminate the slowdown you are facing.
//Create object at the beginning of your application
WlanClient wlanClient = new WlanClient();
//You this code to check wifi availability wherever you need
foreach (WlanInterface _interface in wlanClient.Interfaces)
{
If (_interface.CurrentConnection.wlanAssociationAttributes.dot11Ssid.SSID!=null)
{
// You are connected to wifi
}
}
EDIT: In case you you are not finding dll, direct link. Just reference the Dll and Voila! you are done.
Change your code as
Private Sub GetData()
If My.Computer.Network.IsAvailable AndAlso g_bNetworkAlive
' code to get the data from table
End If
End Sub
You also can check if you have an internet connection by using WebRequest like this:
Private Sub GetData()
If HasInternet AndAlso g_bNetworkAlive Then
'code to get the data from table
End If
End Sub
Public Shared Function HasInternet As Boolean
Return Not (HttpGet("http://www.google.com/") = "Error")
End Function
Public Shared Function HttpGet(url As String) As String
Dim request As WebRequest = WebRequest.Create(url)
request.Method = "GET"
Try
Dim response As WebResponse = request.GetResponse()
Dim dataStream As Stream = response.GetResponseStream()
Dim reader As New StreamReader(dataStream)
Dim responseFromServer As String = reader.ReadToEnd()
reader.Close()
dataStream.Close()
response.Close()
Return responseFromServer
Catch ex As Exception
Return "Error"
End Try
End Function
And you can check the sql connection by using the following function:
Private Function IsDatabaseConnected() As Boolean
Try
Using sqlConn As New SqlConnection("YourConnectionString")
sqlConn.Open()
Return (sqlConn.State = ConnectionState.Open)
End Using
Catch e1 As SqlException
Return False
Catch e2 As Exception
Return False
End Try
End Function
I would simply use try..catch, so if you get exception, you can know, based on its id, why the code failed, and decide what to do next, and finally you can execute some more code regardless of data being retrieved or not
Private Sub GetData()
Try
'code to get the data from table
Catch ex As Exception
' Show the exception's message.
MessageBox.Show(ex.Message)
' Show the stack trace, which is a list of methods
' that are currently executing.
MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
Finally
' This line executes whether or not the exception occurs.
MessageBox.Show("in Finally block")
End Try
End Sub
I have written a web application in which I have not allowed connection pooling for this application. I have written sample code as shown below which gets record from my table 20 times and fill in Data set I have close connection at every time.
But if I look in SQL Server Activity monitor it shows me one connection open in sleeping mode.
anyone tell me why this happens?
does this sleeping connection increase if users increase?
If SQL Server pools my connection then why its pooling if I have not allowed pooling for this application? How can I avoid this?
Code to fetch data
Try
Dim i As Integer
For i = 0 To 20
Dim _db As New commonlib.Common.DBManager(ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString.ToString())
GridView1.DataSource = _db.ExecuteDataSet(CommandType.Text, "SELECT * FROM BT_AppSetting")
GridView1.DataBind()
Next
Catch ex As Exception
Response.Write(ex.Message.ToString())
ex = Nothing
End Try
DBManager constructor
'CONSTRUCTOR WHICH ACCEPTS THE CONNECTION STRING AS ARGUMENT
Public Sub New(ByVal psConnectionString As String)
'SET NOT ERROR
_bIsError = False
_sErrorMessage = Nothing
_cn = New SqlConnection
_sConnectionString = psConnectionString
_cn.ConnectionString = _sConnectionString
Try
_cn.Open()
Catch ex As Exception
_bIsError = True
_sErrorMessage = ex.ToString
ex = Nothing
End Try
End Sub
ExecuteDataSet Function body
Public Function ExecuteDataSet(ByVal CmdType As CommandType, ByVal CmdText As String, ByVal ParamArray Params As SqlParameter()) As DataSet
Try
Dim cmd As New SqlCommand
Dim da As New SqlDataAdapter(cmd)
Dim ds As New DataSet
PrepareCommand(cmd, CmdType, CmdText, Params)
da.Fill(ds)
cmd.Parameters.Clear()
If _cn.State = ConnectionState.Open Then
_cn.Close()
End If
Return ds
Catch ex As Exception
_sErrorMessage = ex.ToString
_bIsError = True
ex = Nothing
Return Nothing
End Try
Please help me.... Waiting for kind reply
1)I THINK sql server does not close the connection right away. That why you see it.
2) Since you are closing the connection you should see only one. Unless your users are running the code at the same time. e.g if it was in a web page and there are 2 users, you will/shoudl see 2 connections.
Also if dont close your connections (just to try) your number of connection will (should :) ) go up.
It is your .net application that pools the connection and not sql server.