ObjectDisposedException obtaining user name in SignalR event - vb.net

I'm logging current SignalR connections in a sql server database. Records are added via the OnConnected and OnReconnected events and removed via the OnDisconnected event.
On deploying to our staging server I am now experiencing an intermittent issue fetching the username of the disconnected user.
This is using SignalR v2.0.3
Public Overrides Function OnDisconnected() As Threading.Tasks.Task
Try
Dim username As String = String.Empty
Try
username = Me.Context.User.Identity.Name ' this is where the error occurs
Catch ex As Exception
_logger.LogWarning(ex, EventLogEntryType.Warning)
End Try
Dim connId = Me.Context.ConnectionId
Dim referer = Me.Context.Headers("Referer")
_connService.RemoveConnection(connId)
Dim msg = New With {.username = username, .connectionId = connId, .referer = referer}
Dim hub = GlobalHost.ConnectionManager.GetHubContext(Of IncidentsHub)()
hub.Clients.All.disconnectionEvent(msg)
Catch ex As Exception
_logger.LogWarning(ex, EventLogEntryType.Error)
End Try
Return MyBase.OnDisconnected()
End Function
I have had to wrap the offending line in an additional try/catch and accept that sometimes there will be no username returned.
The exception seen is:
MOAE - System.ObjectDisposedException: Safe handle has been closed
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at Microsoft.Win32.Win32Native.GetTokenInformation(SafeTokenHandle TokenHandle, UInt32 TokenInformationClass, SafeLocalAllocHandle TokenInformation, UInt32 TokenInformationLength, UInt32& ReturnLength)
at System.Security.Principal.WindowsIdentity.GetTokenInformation(SafeTokenHandle tokenHandle, TokenInformationClass tokenInformationClass)
at System.Security.Principal.WindowsIdentity.get_User()
at System.Security.Principal.WindowsIdentity.GetName()
at System.Security.Principal.WindowsIdentity.get_Name()
at MyProject.IncidentsHub.OnDisconnected() in C:\Projects\...\IncidentsHub.vb:line 95
Can anyone tell me why this is occurring and if there is a more reliable way to obtain this information?

Related

Access Denied issue when connecting to XERO using oAuth2.0

I am creating an application that will allow a user to send Invoices from a local database application to XERO.
Connection works fine when running on my machine at the office but when I port it to the clients terminal server I get this error.
System.Net.HttpListenerException (0x80004005): Access is denied
at System.Net.HttpListener.AddAllPrefixes()
at System.Net.HttpListener.Start()
at XeroConnectionTest.clsXeroAuth2.VB$StateMachine_6_oauth2.MoveNext() in Q:\XeroConnectionTest\XeroConnectionTest\clsXeroAuth2.vb:line 21
This is the code where it fails
Private callbackurl As String = "http://localhost:5000/signin/"
Public Async Function oauth2() As Task(Of Boolean)
Dim redirectUri As String = String.Format(callbackurl)
Dim listener = New HttpListener()
listener.Prefixes.Add(redirectUri)
Try
listener.Start()
stopListening = False
Catch hlex As HttpListenerException
'MsgBox(hlex.ToString)
Form1.TextBox1.Text = hlex.ToString
Return False
End Try
and the error occurs on listener.start() line.
Any help would be gratefully received
Thanks
Frostie

How to properly close a WCF Netnamedpipebinding Channel?

I have a WCF Netnamedpipebinding from my application to an Office Addin. I have noticed that when the office app is busy doing something else that my application locks up when using a WCF method. I have added an example of my code. It appears that the code stops and waits with the channel.close method.
Is the solution to change channel.close to channel.BeginClose ?
What is the the state object I need to pass in to the BeginClose method?
Public Function RequestPersonStatus(ByVal id As String, ByVal email As String)
Using factory As New ChannelFactory(Of IToOffice)(New NetNamedPipeBinding(), New EndpointAddress("net.pipe://localhost/" + XXXXXX))
Dim OfficeChannel As IToOffice = factory.CreateChannel()
Try
OfficeChannel.RequestPersonStatus(id:=id, email:=email)
Catch ex As Exception
Return False
Finally
CloseChannel(CType(OfficeChannel, ICommunicationObject))
End Try
End Using
Return True
End Function
and the closeChannel
Private Sub CloseChannel(ByVal channel As ICommunicationObject)
Try
If channel.State = CommunicationState.Opened Then
Dim caller As New AsyncCallback(AddressOf callback)
channel.BeginClose(caller, New Object)
' channel.Close()
End If
Catch ex As Exception
Log(LogTypes.AllExceptions, "CloseChannel - Error closing the channel. ", ex.ToString)
Finally
channel.Abort()
End Try
End Sub
There seems to be a lot of discussion on what and when to clean up / Dispose / close down channels. I am just posting here what I am now doing and thus my answer to my question.
Private Sub CloseChannel(ByVal channel As ICommunicationObject)
Try
If channel.State <> CommunicationState.Closed AndAlso channel.State <> CommunicationState.Faulted Then
channel.BeginClose(Sub(asr)
Try
channel.EndClose(asr)
Catch
channel.Abort()
End Try
End Sub, Nothing)
Else
channel.Abort()
End If
Catch commEx As CommunicationException
channel.Abort()
Catch ex As Exception
channel.Abort()
Finally
End Try
End Sub
As far as I know, most of the cases like the timeout error/connection/communication error are caused by that the channel/client proxy is not properly closed. Putting the client proxy/Service Channel in a using block will eliminate the problem.
using (ServiceReference1.ServiceClient client=new ServiceClient())
{
var result = client.Test();
Console.WriteLine(result);
}
The Using statement is useful for automatically closed the service proxy/service communication channel after completing the invocation. Besides, Service client proxy is similar to the communication channel created by the ChannelFactory.
Feel free to let me know if there is anything I can help with.

SQL Connection timeout not working as expected

I made following function to check whether connection is established or not.
Here I have made timeout = 15 seconds.
It works most of the time.
But sometime it throws exception before time.
So if I give same connectionstring, sometimes it works as per timeout and sometime it expires before time.
What is wrong with timeout?
Public Function IsDBExist(ByVal strConnectionString As String) As Boolean
Try
Using connection As New SqlConnection
Dim str As New SqlConnectionStringBuilder(strConnectionString)
str.ConnectTimeout = 15
connection.ConnectionString = str.ToString()
connection.Open()
End Using
Return True
Catch ex As Exception
Return False
End Try
End Function
Generally it means the connection string provided allowed the client to reach an sql-server instance but then something went wrong. For example, database name specified doesn't exist or the user has no privileges to see it.

Preventing exception from lack of internet connectivity

I have a simple Windows Form application. I have used a Timer and on Timer interval I am checking online database for values and updating it on the form.
Private Sub Timer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer.Tick
Try
String ConnectionString = globalConnString
Dim SQL As String = "SELECT AnnouncementID, AnnoucementText FROM tblAnnouncements"
Dim conn As SqlConnection = New SqlConnection(ConnectionString)
conn.Open()
Dim adapter As SqlDataAdapter = New SqlDataAdapter(SQL, conn)
Dim ds As DataSet = New DataSet("Announcements")
adapter.Fill(ds)
UpdateForm(ds)
Catch ex As Exception
LogError("Timer_Tick", ex)
End Try
End Sub
Now sometimes the internet is disconnected or there is very slow internet. For that I have created a function as below,
Public Function CheckInternetConnection() As Boolean
Try
If My.Computer.Network.IsAvailable = True Then
Return My.Computer.Network.Ping("8.8.8.8")
Else
Return False
End If
Catch ex As Exception
Return False
End Try
End Function
This function is pinging google public DNS but in my application this is the IP address of my database server. I have wrapped the functionality inside Timer_Tick inside CheckInternetConnection so that when there is internet connection only then the database operation is made.
Now problem I am facing is that when I switch internet (using two different wifi conenctions) and when I turn on and off the internet then very rarely the code is broken and exception is created for line adapter.Fill(ds). My guess is that it is because at the start of function there is internet connectivity available and the condition for internet check is passed. When program starts to execute database operation then at that point rarely internet is gone so the program raises exception.
The example I have given is for one function and the actual application (which is quite big and written long time ago) is like this and I have to fix the connectivity issue within the same code. How can I make this fool proof that no database code is ever reached when there is no internet connectivity?
Use a loop to try multiple times. E.g.
int numTries = 3;
while (numTries > 0) {
numTries--;
try {
// open connection, fill
// your code
break; // got here means success
} catch {
if (numTries == 0)
throw; // propagate exception to next level
Thread.Sleep(500); // optional sleep
}
}

Error not being caught (AsyncCallback)

Hi there i have a piece of code which connects using sockets to a server
Try
'Connect To The Server
Dim socketclient As New TcpClient
Dim success
Dim result
result = socketclient.BeginConnect(ip, port, socket.EndConnect, socketclient)
success = result.AsyncWaitHandle.WaitOne(5000, True)
If socketclient.Connected = False Then
Throw New Exception("Server is offline")
End If
catch ex as exception
End Try
As you can see. if a server is offline, my try-catch setup doesn't catch the error "host is unknown" i believe this is because the error occurs during the async call. IF this is true, how does one catch an error in an async call?
You should end the async operation.
Your wait is totally unnecessary, if you just want to block waiting for the connection just call EndConnect over the socket ;)
http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.endconnect.aspx