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

53 次查看(过去 30 天)
啓嗣
啓嗣 2024-8-1
评论: 啓嗣 2024-8-23,5:20
お疲れ様です。
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,6:31
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,5:20
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 中查找有关 C 共有ライブラリの統合 的更多信息

产品


版本

R2023b

Community Treasure Hunt

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

Start Hunting!