Как использовать командную строку Matlab из .NET без привязки?

54
6

Наконец-то я нашел способ использовать командную строку Matlab из .NET без ссылки:


    Записывать переменные из .NET в MAT файл с использованием dll dll dll csmatio Дэвида А. Зиера.


    Прочитайте файл из 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();

спросил(а) 2009-07-12T03:38:00+04:00 10 лет, 10 месяцев назад
1
Решение
76

Гораздо лучшим вариантом является флаг -wait для matlab. Он сообщает, что стартер Matlab заканчивается вместе с основным процессом matlab.

ответил(а) 2013-01-27T19:51:00+04:00 7 лет, 3 месяца назад
53

Не уверен, что я полностью понимаю вопрос (вы, по сути, пытаетесь обнаружить, когда процесс Matlab заканчивается правильно?), но не могли бы вы найти основной процесс приложения matlab и дождаться его выхода? то есть примерно так:


process.WaitForExit();  //only waits for the launcher process to finish
//but now matlab should be running in a new process...
var matlabProcess = Process.GetProcessesByName("whatever process is called");
//assuming only one matlab instance running...
//you'd probably want to write some defensive code here...
matlabProcess[0].WaitForExit();

Похоже, это было бы проще, чем пытаться посмотреть, как он меняет файлы и угадывает, когда закончится...

ответил(а) 2009-07-21T05:19:00+04:00 10 лет, 10 месяцев назад
37

Я немного изменил решение, чтобы он работал у меня


var previousProcesses = Process
.GetProcessesByName("Matlab")
.Select(a => a.Id)
.ToArray();
var process = Process.Start(startInfo);
process.WaitForExit();
var newProcessRunning = Process
.GetProcessesByName("Matlab")
.Where(a => !previousProcesses.Contains(a.Id));
if (newProcessRunning.Count() != 0)
newProcessRunning.First().WaitForExit();

ответил(а) 2012-11-07T17:02:00+04:00 7 лет, 6 месяцев назад
39

Как насчет определения фактического процесса для отдельного потока и вызова WaitForExit на нем? Возможно, используйте программу командной строки tasklist, чтобы получить PID всех процессов MATLAB и отфильтровать PID того, который у вас есть.


В качестве альтернативы может существовать структура .NET(возможно, связанная с process), которая может возвращать дочерний поток process и ждать его.


К сожалению, я не знаю деталей, но стоит попробовать найти этот проспект.

ответил(а) 2009-07-24T01:11:00+04:00 10 лет, 10 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема