1

リンクせずに.NETからコマンドラインMatlabを使用する方法を最終的に発見しました:

  1. David A. Zier の「csmatio」dll を使用して、.NET から MAT ファイルに変数を書き込みます。

  2. Matlab からファイルを読み取り、処理して、結果を MAT ファイルに保存します。

    var process = new Process()
    {
        StartInfo = new ProcessStartInfo()
        {
            FileName = MatlabExecutableFileName,
            Arguments = "-nodisplay " + 
               "-nojvm " +
               " -r \"somecommands; " + 
               "save FILENAME OUTPUTVARIABLES; " +
               "exit;\""
        }
    };
    process.Start();
    
  3. 最悪の部分:プロセスが終了するまで待ちます。

    単純なアプローチ:

    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();
4

4 に答える 4

3

はるかに優れたオプションは、-waitmatlab のフラグです。メインの matlab プロセスと共に終了するように、matlab スターターに指示します。

于 2013-01-27T16:51:52.857 に答える
1

質問を完全に理解しているかどうかはわかりませんが (基本的に、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-21T02:19:28.387 に答える
0

別のスレッドの実際のプロセスを決定し、WaitForExitそれを呼び出すのはどうですか? おそらく、コマンド ライン プログラムtasklistを使用して、すべての MATLAB プロセスの PID を取得し、所有しているプロセスの PID を除外します。

processあるいは、の子スレッドを返し、processそれを待機できる.NET 構造 (おそらく に関連する) が存在する可能性があります。

残念ながら詳細はわかりませんが、その道を探してみてください。

于 2009-07-23T22:11:02.823 に答える
0

ソリューションを少し変更したので、うまくいきました

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-07T14:02:53.940 に答える