MATLABRuntimeインスタンスを終了せず、使い回す方法。
53 views (last 30 days)
Show older comments
お疲れ様です。
MATLAB Compiler SDKを用いてMATLAB関数をパッケージ化し、C#.NETアセンブリに統合したいと考えています。
MATLABRuntime.StartMATLABAsyncを最初に起動することでMATLABRuntimeインスタンスを作成し、そのあとのタスクでMATLABRuntimeインスタンスを1度毎に終了するのではなく使い回したいと考えています。
しかし、下記のコードを実行したところ2度目のメソッド実行時に「破棄されたオブジェクトにアクセスできません。」というエラーが出現します。1度目のメソッド実行時にMATLABRuntimeインスタンスを破棄しない方法はありますでしょうか。
エラー内容
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1744561/image.png)
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
0 Comments
Accepted Answer
Madheswaran
on 20 Aug 2024 at 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.
More Answers (0)
See Also
Categories
Find more on C 共有ライブラリの統合 in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!