启动外部程序时保持WPF主窗口响应的方法及启动方案优化问询
解决WPF窗口冻结问题
你的当前代码直接调用Process.Start本身不会阻塞UI线程,但如果后续有同步读取进程输出或等待操作,才会导致窗口冻结。以下是正确的异步实现方式,能保证UI正常响应:
private static async Task ProcessStarterAsync(string directoryLocation, string cmdCommand) { ProcessStartInfo mcTask = new ProcessStartInfo(); mcTask.FileName = "cmd.exe"; mcTask.WindowStyle = ProcessWindowStyle.Hidden; mcTask.Arguments = "/c " + cmdCommand; mcTask.RedirectStandardInput = true; mcTask.RedirectStandardOutput = true; mcTask.RedirectStandardError = true; mcTask.WorkingDirectory = directoryLocation; mcTask.UseShellExecute = false; // 必须设置此属性才能启用流重定向 using Process process = Process.Start(mcTask); // 使用异步方法读取输出,避免阻塞UI线程 string output = await process.StandardOutput.ReadToEndAsync(); string error = await process.StandardError.ReadToEndAsync(); await process.WaitForExitAsync(); }
在UI事件中调用时,使用await关键字即可:
private async void LaunchButton_Click(object sender, RoutedEventArgs e) { await ProcessStarterAsync(@"你的MultiMC安装目录", "MultiMC.exe -l [InstanceName]"); }
注意:UI事件方法可以用async void,但其他业务方法建议用async Task规范。
更优的MultiMC启动方式
完全不需要通过cmd中转,直接启动MultiMC.exe并传入参数即可,减少额外开销:
private static async Task StartMultiMCAsync(string multiMCDirectory, string instanceName) { ProcessStartInfo mcTask = new ProcessStartInfo(); mcTask.FileName = Path.Combine(multiMCDirectory, "MultiMC.exe"); mcTask.Arguments = $"-l {instanceName}"; mcTask.WorkingDirectory = multiMCDirectory; using Process process = Process.Start(mcTask); // 若不需要等待MultiMC退出,可直接移除下面这行 await process.WaitForExitAsync(); }
这种方式启动效率更高,同时异步执行也不会阻塞UI。
内容的提问来源于stack exchange,提问作者Loading...
相关产品推荐
相关产品推荐

