Reputation: 5968
I have a VB.Net application and I create some objects via Remoting.
Sometimes (not always) the creation of the remoting objects blocks and the application freezes without anyexception thrown and even if the server is ok. I tried to let it running but after 15 minutes, still nothing happening. But if I stop the application and re-run it immediatly it works perfectly.
Is there anyway to know what's wrong with that ? or a way to rerun the creation of the remote object after a timeout ?
Here is the code I use to create the remote objects:
URL = "tcp://" & ServerIPAddress.ToString & ":" & ServerRemotingPort.ToString & "/TechnicalDatabase"
RemoteObject = CType(Activator.GetObject(GetType(TechnicalDatabase.TechnicalDatabaseObject), URL), TechnicalDatabase.TechnicalDatabaseObject)
This problems happends roughly once in 10 times.
Upvotes: 3
Views: 266
Reputation: 9981
The following code is to be viewed as an example/ a simple fix. It doesn't explain the "why". It runs the code in a BackgroundWorker
and uses a Timer
to timeout/abort the worker.
Imports System.Runtime.Remoting
Imports System.ComponentModel
Imports System.Threading.Thread
Public Class Form1
Public Sub New()
Me.InitializeComponent()
Me.bgWorker = New BackgroundWorker()
Me.bgWorker.WorkerSupportsCancellation = True
Me.bgTimer = New System.Windows.Forms.Timer
Me.bgTimer.Interval = 60000 '<-- Timeout after 1 minute.
End Sub
Private Sub Connect(ipAddress As String, portNumber As Integer, db As String)
If (Me.bgWorker.IsBusy) Then
Throw New Exception("Worker is busy.")
End If
Dim [error] As Exception = Nothing
Try
AddHandler Me.bgTimer.Tick, New EventHandler(AddressOf Me.OnTimeout)
AddHandler Me.bgWorker.DoWork, New DoWorkEventHandler(AddressOf Me.OnDoWork)
AddHandler Me.bgWorker.RunWorkerCompleted, New RunWorkerCompletedEventHandler(AddressOf Me.OnWorkCompleted)
Me.bgTimer.Enabled = True
Me.bgWorker.RunWorkerAsync(String.Format("tcp://{0}:{1}/{2}", ipAddress, portNumber, db))
Catch ex As Exception
[error] = ex
Me.bgTimer.Enabled = False
RemoveHandler Me.bgTimer.Tick, New EventHandler(AddressOf Me.OnTimeout)
RemoveHandler Me.bgWorker.DoWork, New DoWorkEventHandler(AddressOf Me.OnDoWork)
RemoveHandler Me.bgWorker.RunWorkerCompleted, New RunWorkerCompletedEventHandler(AddressOf Me.OnWorkCompleted)
End Try
If (Not [error] Is Nothing) Then
Throw [error]
End If
End Sub
Private Sub OnDoWork(sender As Object, e As DoWorkEventArgs)
Me.bgThread = Thread.CurrentThread
Try
e.Result = CType(Activator.GetObject(GetType(TechnicalDatabase.TechnicalDatabaseObject), DirectCast(e.Argument, String)), TechnicalDatabase.TechnicalDatabaseObject)
Catch ex As ThreadAbortException
e.Cancel = True
Thread.ResetAbort()
Catch ex As Exception
Throw ex
End Try
End Sub
Private Sub OnWorkCompleted(sender As Object, e As RunWorkerCompletedEventArgs)
Me.bgTimer.Enabled = False
Me.bgThread = Nothing
RemoveHandler Me.bgTimer.Tick, New EventHandler(AddressOf Me.OnTimeout)
RemoveHandler Me.bgWorker.DoWork, New DoWorkEventHandler(AddressOf Me.OnDoWork)
RemoveHandler Me.bgWorker.RunWorkerCompleted, New RunWorkerCompletedEventHandler(AddressOf Me.OnWorkCompleted)
If (Not e.Error Is Nothing) Then
MessageBox.Show(e.Error.Message, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
ElseIf (e.Cancelled) Then
MessageBox.Show("Worker cancelled.", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
Dim remoteObject As Object = CType(e.Result, TechnicalDatabase.TechnicalDatabaseObject)
MessageBox.Show("Success!", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub
Private Sub OnTimeout(sender As Object, e As EventArgs)
Me.bgTimer.Enabled = False
If (Not Me.bgThread Is Nothing) Then
Me.bgThread.Abort()
End If
End Sub
Private bgWorker As BackgroundWorker
Private bgTimer As System.Windows.Forms.Timer
Private bgThread As Thread
End Class
To connect:
Me.Connect(ServerIPAddress.ToString(), ServerRemotingPort, "TechnicalDatabase")
Source of inspiration:
Upvotes: 2