MATLABRunt​imeインスタンスを​終了せず、使い回す方​法。

조회 수: 5 (최근 30일)
啓嗣
啓嗣 2024년 8월 1일
댓글: 啓嗣 2024년 8월 23일
お疲れ様です。
MATLAB Compiler SDKを用いてMATLAB関数をパッケージ化し、C#.NETアセンブリに統合したいと考えています。
MATLABRuntime.StartMATLABAsyncを最初に起動することでMATLABRuntimeインスタンスを作成し、そのあとのタスクでMATLABRuntimeインスタンスを1度毎に終了するのではなく使い回したいと考えています。
しかし、下記のコードを実行したところ2度目のメソッド実行時に「破棄されたオブジェクトにアクセスできません。」というエラーが出現します。1度目のメソッド実行時にMATLABRuntimeインスタンスを破棄しない方法はありますでしょうか。
エラー内容
C#.NETコード
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using MathWorks.MATLAB.Runtime;
using MathWorks.MATLAB.Types;
namespace Sample_MATLABAsync
{
class Program
{
private static Task<MATLABRuntime> workflowTask;
static async Task CallMATLAB(Task<MATLABRuntime> matlabTask)
{
try
{
// Await the MATLAB Runtime task to complete and get the MATLAB instance
using (dynamic matlab = await matlabTask)
{
// Call a MATLAB function using the MATLAB instance
matlab.mydisp(new RunOptions(nargout: 0), "Hello, CallMATLAB!");
}
}
catch (OperationCanceledException)
{
Console.WriteLine("MATLAB call was cancelled.");
throw; // Re-throwing to be caught in the calling method
}
}
static async Task AsyncStartMATLAB()
{
// Create a CancellationTokenSource to control task cancellation
CancellationTokenSource src = new CancellationTokenSource();
// Schedule the cancellation after 10 seconds
src.CancelAfter(TimeSpan.FromSeconds(100));
await Task.CompletedTask.ConfigureAwait(false);
workflowTask = MATLABRuntime.StartMATLABAsync("mydisp.ctf", src.Token);
}
static async Task Main(string[] args)
{
// 総合時間
var sw1 = new Stopwatch();
// TaskA時間
var sw2 = new Stopwatch();
// TaskB時間
var sw3 = new Stopwatch();
sw1.Start();
try
{
// Start the MATLAB Runtime asynchronously with cancellation token
await AsyncStartMATLAB();
if(workflowTask == null)
{
Console.Error.WriteLine("MATLAB Runtime task was not initialized.");
return;
}
sw2.Start();
Task A = CallMATLAB(workflowTask);
await A;
sw2.Stop();
TimeSpan span2 = sw2.Elapsed;
Console.WriteLine($"Task A time:{span2.TotalSeconds}");
Console.WriteLine("Now Task A is running.");
// Await the completion of the MATLAB Runtime task
// This is a non-blocking wait and will throw an exception if cancelled
Console.WriteLine("Task A is completed successfully!");
sw3.Start();
Task B = CallMATLAB(workflowTask);
await B;
sw3.Stop();
TimeSpan span3 = sw3.Elapsed;
Console.WriteLine($"Task B time:{span3.TotalSeconds}");
}
catch (OperationCanceledException)
{
// Handle the cancellation of the task
Console.Error.WriteLine("Task was cancelled before completion.");
}
catch (Exception ex)
{
// Handle any other exceptions that might occur
Console.Error.WriteLine($"An error occurred: {ex.Message}");
throw; // Optional: rethrow if you want to escalate the error
}
sw1.Stop();
TimeSpan span1 = sw1.Elapsed;
Console.WriteLine($"Total Opt time:{span1.TotalSeconds}");
}
}
}
MATLABコード
function mydisp(a)
disp(a);
disp("mydispの実行を確認")
nextdisp();
end
function nextdisp()
disp("next dips");
end

채택된 답변

Madheswaran
Madheswaran 2024년 8월 20일
Hi 啓嗣,
It appears that the issue you're encountering is related to the management of the MATLAB Runtime instance within your application. The problem arises from the use of the “using” statement in the “CallMATLAB” task, which automatically disposes of the MATLAB Runtime object when the block is exited. This behaviour is not you are expecting if you intend to keep the MATLAB Runtime instance alive for the entire duration of your program.
To address this, you should manage the lifetime of the “MATLABRuntime” instance manually, rather than relying on the “using” statement. Here is the modified code for the Task “CallMATLAB”:
static asyncTask CallMATLAB(Task<MATLABRuntime> matlabTask)
{
try
{
dynamicmatlab =await matlabTask;
matlab.mydisp(newRunOptions(nargout: 0), "Hello, CallMATLAB!");
}
catch(OperationCanceledException)
{
// (existing exception handling)
}
}
Also, you'll need to ensure that you dispose of the “MATLABRuntime” instance properly when you're completely done with it.
static asyncTask Main(string[] args)
{
// (existing code)
try
{
// (existing code)
// Dispose of the MATLAB Runtime when done
(awaitworkflowTask).Dispose();
}
catch(Exception ex)
{
// (existing error handling)
}
}
This approach should prevent the MATLAB Runtime instance from being disposed of too early, allowing it to be reused for the subsequent function calls.
  댓글 수: 1
啓嗣
啓嗣 2024년 8월 23일
Thank you for your response, Madheswaran.
By following your advice and making the necessary corrections, I was able to reuse the MATLAB instance without destroying it.
Thank you very much.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 ビッグ データの処理에 대해 자세히 알아보기

제품


릴리스

R2023b

Community Treasure Hunt

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

Start Hunting!