我终于发现了一种无需链接即可从 .NET 使用命令行 Matlab 的方法:
使用 David A. Zier 的“csmatio”dll 将变量从 .NET 写入 MAT 文件。
从 Matlab 读取文件,对其进行处理并将结果保存到 MAT 文件中:
var process = new Process() { StartInfo = new ProcessStartInfo() { FileName = MatlabExecutableFileName, Arguments = "-nodisplay " + "-nojvm " + " -r \"somecommands; " + "save FILENAME OUTPUTVARIABLES; " + "exit;\"" } }; process.Start();
最糟糕的部分:等到过程完成。
天真的方法:
process.WaitForExit();
不起作用,因为 matlab 在新线程中生成主应用程序
观察输出文件的变化是很棘手的:
new FileSystemWatcher(MatlabPath, fileName) .WaitForChanged(WatcherChangeTypes.All)
由于此类上的错误而无法正常工作。
当前工作的代码更长:
using (var watcher = new FileSystemWatcher(MatlabPath, fileName)) { var wait = new EventWaitHandle(false, EventResetMode.AutoReset); watcher.EnableRaisingEvents = true; watcher.Changed += delegate(object sender, FileSystemEventArgs e) { wait.Set(); }; foreach(var i in Enumerable.Range(0, 2)) { if (!wait.WaitOne(MillissecondsTimeout)) { throw new TimeoutException(); } } Thread.Sleep(1000); }
但我担心最后一行代码。上面的代码块是为了避免它而编写的,但我不知道还能做什么。这段时间在某些计算机上过多,而在其他计算机上过少。
解决方案
var previousProcesses = Process
.GetProcessesByName("Matlab")
.Select(a => a.Id)
.ToArray();
process.Start();
process.WaitForExit();
var currentProcess = Process
.GetProcessesByName("Matlab")
.Where(a => !previousProcesses.Contains(a.Id))
.First();
currentProcess.WaitForExit();