Question

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.

Was it helpful?

Solution

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:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top