Событие OutputDataReceived происходит в каждой строке, записанной в stdout (а затем в последний раз с Data == null, когда это будет сделано, как вы, кажется, уже знаете), поэтому вы получаете это исключение, потому что вы пытаетесь сделать SetResult несколько раз.
Предполагая, что вы хотите сохранить ту же структуру для кода, ваше предложение else должно измениться на tcs.SetResult (e.Data.ToString ()); для сохранения строки в e.Data в StringBuffer или List или где-либо еще (в нее не входит перевод строки, поэтому, если вы хотите сохранить ее, вам нужно будет добавить ее обратно самостоятельно).
Тогда ваше предложение if выполнит tcs.SetResult (stringBuffer.ToString ()); (или, тем не менее, вы решили сохранить строки) перед выполнением outputWaitHandle.Set ()
Убедитесь, что у вас есть RedirectStandardOutput = true и RedirectStandardError = false, поскольку в противном случае процесс может блокироваться, если он пишет достаточно stderr, и вы запросили его перенаправить, но не прочитали его. Подробнее об этом ищите в тупике в документе @ http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standarderror.aspx