2009-07-12 44 views
1

我終於發現了一種從.NET中使用命令行Matlab的無連接:從.NET如何使用命令行從.NET的Matlab沒有鏈接?

  1. 寫變量使用大衛A.紫兒的「csmatio」一個DLL文件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); 
    } 
    

    但我關心的代碼的最後一行。上面的代碼塊是爲了避免它而編寫的,但我不知道還有什麼要做。這段時間在某些計算機上太多而在其他計算機上太少。

SOLUTION

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

回答

3

一個更好的選擇是MATLAB中的-wait標誌。它告訴matlab啓動器與主matlab進程一起終止。

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

好像那會比試圖觀看它更改的文件&猜測簡單,當其完成......

+0

完美!有效! – 2009-07-23 23:34:00

0

如何確定實際進程的單獨的線程,並呼籲WaitForExit在上面?也許可以使用命令行程序tasklist來獲取所有MATLAB進程的PID,並過濾掉所有MATLAB的PID。

或者,可能有一個.NET結構(可能與process有關),它可能會返回process的子線程並等待它。

不幸的是,我不知道細節,但值得一試的搜索大道。

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