2013-10-20

Running a Process in F#

For SourceLink, I'm going to add the ability to run pdbstr to update the pdb instead of modifying it directly because of a bug I'm having trouble figuring out. After reading a stackoverflow question about using async with a process, I decided to give it a try. I got it working using the Async.GuardedAwaitObservable in the Fsharpx.Core library. SourceLink does not need the async support, but it was a fun technical challenge. Hopefully, someone else can elaborate on its merits (or flaws).

console output

C:\Program Files (x86)\MSBuild\12.0\Bin\amd64\MSBuild.exe
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe
exit code: 0

INFO: Could not find files for the given pattern(s).
exit code: 1

Program.fs

Here I run "where msbuild' and "where fsc". msbuild is on a couple on my places on my PATH environment variable, but fsc is not, so it correctly returns an error code of 1. I exposed the stdout and stderr streams through events. You can connect to the F# events using Event.add, Observable.add, or Observable.subscribe. It isn't necessary here to unsubscribe, but it may be important to avoid memory leaks in other situations. FSharpx.Core adds support for Async.AwaitObservable which should be used in favor of Async.AwaitEvent. The "where fsc" process runs the async code synchronously, but it demonstrates that code path working. :)
Loading ....

Process.fs

Loading ....
I also ran several processes at the same time using Async.Parallel as well as Task.WaitAll on the async and sync versions. All had similar results. Perhaps adding cancellation would be a reason to use an async model here, but there was no performance gain for using the async over sync in my case where nothing was resource bound.