如何干净地停止运行 matlab dll 函数的 .NET 线程
Posted
技术标签:
【中文标题】如何干净地停止运行 matlab dll 函数的 .NET 线程【英文标题】:How to cleanly stop a .NET thread that is running a matlab dll function 【发布时间】:2017-12-12 21:55:21 【问题描述】:我用这个函数编译了一个带有命名空间 flagTest 和类名 test 的 Matlab DLL:
function [ ] = flagTest( flag )
while flag
disp(flag);
pause(1);
end
end
我可以像这样在 c# 中调用这个 dll 函数:
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;
namespace ConsoleApplication1
class Program
static void Main(string[] args)
//create test class object
flagTest.test T = new flagTest.test();
MWLogicalArray flag = new MWLogicalArray(true);
//call matlab function flagTest
T.flagTest(flag);
很抱歉,由于我将命名空间和函数都称为flagTest
,因此造成任何混淆。
我现在要做的是将这个T.flagTest(flag)
函数调用放在一个线程上(我知道该怎么做),并在用户单击UI 上的按钮时将flag
的值更改为false
停止线程。在我们应用程序中真正的 matlab 函数中,我需要做一些工作,例如完成当前文件的读取并将内存中的数据写入磁盘,然后才能停止函数线程。我不能在 matlab 函数中不做任何事情就停止线程。
我想知道是否有任何方法可以实现此功能,因为我无法弄清楚如何通过引用将对象从 .NET 传递到 Matlab。
【问题讨论】:
【参考方案1】:为什么不将控制循环的标志封装到test
类中?例如:
classdef test < handle
properties (Access = private)
Running
end
methods
function Start(this)
if (this.Running)
disp('Already Running');
return;
end
this.Running = true;
disp('Started');
while (this.Running)
pause(1);
disp('Running');
end
disp('Stopped');
end
function Stop(this)
this.Running = false;
end
end
enn
然后,在您的 C#
程序集中:
namespace ConsoleApplication1
public static class Program
public static void Main(String[] args)
flagTest.test T = new flagTest.test();
T.Start();
while (true)
String command = Console.ReadLine();
if (command.ToLowerInvariant() == "stop")
T.Stop();
break;
话虽如此,这种方法与多线程无关。如果你想使用多线程,你必须考虑三个重要的事情:
-
如何在线程被杀死时保存您的工作人员进度
如何实现取消信号属性
如何控制取消信号
这只是一个例子,但必须改进:
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
List<Thread> threads = new List<Thread>();
for (Int32 i = 0; i < 5; ++i)
flagTest.test T = new flagTest.test();
token.Register(() => T.Stop());
Thread thread = new Thread(() => T.Start());
thread.IsBackground = true;
threads.Add(thread);
thread.Start();
然后,当用户要求取消时,只需调用:
cts.Cancel();
cts.Dispose();
【讨论】:
托马索,非常感谢您的帮助!但是,我无法弄清楚如何将此类编译为 .NET dll,因为我们似乎只能使用 matlab deploytool 编译独立函数。我阅读了this,但仍然没有 100% 理解它是如何工作的,因为该链接中的示例不会直接在 C++ 代码中生成GlobalData
类,因此我们不能使用该类并调用该类中的另一个方法。跨度>
我正在考虑一个替代方案:将所有循环带到 Matlab 之外,并将它们放入 .NET 程序集中。然后,编写您的 Matlab 函数,以便它可以处理具有确定偏移量的数据,如果可能的话,例如 DoWork(from,to)。至此,您将能够完全控制您的线程,因为它们是单面的。
是的。这将是我想到的另一种选择,需要大量将 Matlab 代码重写为 c#,我的队友决定不使用它......我能够将 matlab 函数包装在一个matlab 类并将该函数编译为 dll 并从 c# 调用它。但是,我面临的问题是我不知道如何将 matlab 类转换为 MWArray 对象,因此我可以更改类中的 flag 属性。我认为这将是我在这里提出的另一个问题。再次非常感谢您。
虽然我确信有一种方法可以使用对象实例,但这个答案提供了另一种解决方案:***.com/questions/8841146/…以上是关于如何干净地停止运行 matlab dll 函数的 .NET 线程的主要内容,如果未能解决你的问题,请参考以下文章
如何查看从 Matlab 中 Mex 函数使用的 DLL 调用的 printf 的输出?
C#&MatLab:我是不是需要 MCR 才能在任何计算机上运行 MWArray.dll?
使用 Matlab 运行时无法找到 mclmcrrt*.dll