How to correctly abort a running Matlab function/thread in a .NET Assembly in .NET8?

5 次查看(过去 30 天)
Dear MathWorks team
In our .NET Framework 4.7.2 application we instanciate a class from a Matlab .NET assembly and call one function to calculate.
The call is done in a own background thread of the application.
If the calculation takes too long or the calculation request has been canceled, we just aborted the .NET thread with thread.Abort().
.NET core (at least v8) does not support the Abort() function anymore. The only general alternative suggestion I could find is to outsource the call into an own process and then kill the process if required. This seems to be quite complicated and Matlab takes a few seconds to initialize on the first call, which is too slow for us.
Is there any best practice / example how to achieve this?
Thanks in advance
Public Sub New(ByVal theTimeout As Integer, theData As Object, theWorkerMethod As TheWorkerDelegate, theCompleteCallback As CompleteCallbackDelegate, theSynchObj As ISynchronizeInvoke)
_theData = theData
_theCompleteCallback = theCompleteCallback
_theWorkerMethod = theWorkerMethod
_theSyncObject = theSynchObj
If theTimeout > 0 Then
_timeoutTimer = New WcsTimer(theTimeout * 1000, WcsTimer.TimerMode.SingleShot)
AddHandler _timeoutTimer.TimeElapsed, AddressOf _timeoutTimerElapsed
End If
_theThread = New Threading.Thread(AddressOf _startWorkerThread)
_theThread.Name = "Matlab Supervision Thread"
_theThread.Start()
End Sub
Public Sub Abort()
_stopTimeoutTimer()
If _theThread IsNot Nothing AndAlso _theThread.IsAlive Then
_theThread.Abort()
End If
_theThread = Nothing
End Sub
Private Sub _startWorkerThread()
Dim theEx As Exception = Nothing
Try
_theWorkerMethod(_theData) -> Matlab call
Catch ex As Exception
theEx = ex
End Try
_stopTimeoutTimer()
Dim p As Object() = {_theData, False, theEx}
_theSyncObject.Invoke(_theCompleteCallback, p)
End Sub
Private Sub _timeoutTimerElapsed(sender As Object, e As EventArgs)
WcsTrace.Log(WcsTrace.Category.Detailed, $"********* BackgroupWorker Timeoute -> Abort **************")
Abort()
_theCompleteCallback(_theData, True, Nothing)
End Sub

回答(1 个)

Githin George
Githin George 2024-8-29
If creating a separate process is not helpful, you could try using Cancellation Token to signal that a task should stop. The task needs to periodically check for this signal and gracefully exit.
The following code shows the usage of the Cancellation Token:
Imports System.Threading
Imports System.Threading.Tasks
Public Class MatlabWorker
Private _theData As Object
Private _theCompleteCallback As CompleteCallbackDelegate
Private _theWorkerMethod As TheWorkerDelegate
Private _theSyncObject As ISynchronizeInvoke
Private _cancellationTokenSource As CancellationTokenSource
Public Sub New(ByVal theTimeout As Integer, theData As Object, theWorkerMethod As TheWorkerDelegate, theCompleteCallback As CompleteCallbackDelegate, theSynchObj As ISynchronizeInvoke)
_theData = theData
_theCompleteCallback = theCompleteCallback
_theWorkerMethod = theWorkerMethod
_theSyncObject = theSynchObj
_cancellationTokenSource = New CancellationTokenSource() // Initialize CancellationTokenSource
If theTimeout > 0 Then
_cancellationTokenSource.CancelAfter(theTimeout * 1000) //Set timeout for cancellation
End If
Task.Run(Sub() _startWorkerTask(_cancellationTokenSource.Token)) // Use Task to start the worker method
End Sub
Public Sub Cancel()
_cancellationTokenSource.Cancel() //Request cancellation
End Sub
Private Async Function _startWorkerTask(cancellationToken As CancellationToken) As Task
Dim theEx As Exception = Nothing
Try
Await Task.Run(Sub() _theWorkerMethod(_theData, cancellationToken), cancellationToken) // Pass CancellationToken to the worker method
Catch ex As OperationCanceledException
// Handle cancellation
Catch ex As Exception
theEx = ex
End Try
Dim p As Object() = {_theData, cancellationToken.IsCancellationRequested, theEx}
_theSyncObject.Invoke(_theCompleteCallback, p) // Invoke callback with cancellation status
End Function
End Class
// Worker method signature should accept a CancellationToken
Public Delegate Sub TheWorkerDelegate(data As Object, cancellationToken As CancellationToken)
Here is an overview of this approach:
  • Thread Management: Transitioned from Thread to Task for better scalability and resource management.
  • Cancellation: Introduced a cooperative cancellation model using CancellationToken. We are adding handling for OperationCanceledException to differentiate between cancellations and other exceptions.
  • Timeout: Simplified timeout handling using CancelAfter.
Additional Reference Documentations:

类别

Help CenterFile Exchange 中查找有关 Get Started with Microsoft .NET 的更多信息

产品


版本

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by