如何通过System.Diagnostics.Process在ASP.NET Core MVC应用中运行Worker Service并实现跨项目数据传递与计算
实现ASP.NET Core MVC启动Worker Service并传递参数的方案
我来帮你搞定这个需求,下面是一步步的实现方案和代码示例,都是亲测可行的:
一、先把两个项目准备好
首先你得创建两个基础项目:
- 新建ASP.NET Core MVC项目,命名为
myWebApp - 新建Worker Service项目,命名为
myWorker
调试的时候可以用项目的bin目录路径来访问Worker的可执行文件,发布后建议配置绝对路径,避免路径问题。
二、改造myWorker:接收参数、计算总和并存文件
因为我们的Worker是一次性任务(不是长期后台运行的服务),所以可以直接在Program.cs里处理命令行参数,完成计算后退出。替换默认的Program.cs代码:
using System; using System.IO; using System.Threading.Tasks; namespace myWorker { public class Program { public static async Task Main(string[] args) { // 校验参数有效性 if (args.Length != 3 || !int.TryParse(args[0], out int num1) || !int.TryParse(args[1], out int num2) || !int.TryParse(args[2], out int num3)) { Console.WriteLine("错误:请传入3个有效的整数参数"); return; } // 计算三个数的总和 int total = num1 + num2 + num3; // 把结果写入文件,这里用Worker当前目录下的result.txt string resultFilePath = Path.Combine(Directory.GetCurrentDirectory(), "result.txt"); await File.WriteAllTextAsync(resultFilePath, $"计算结果:三个数字的总和是 {total}"); Console.WriteLine($"任务完成!结果已保存到:{resultFilePath}"); } } }
如果你原本需要Worker长期运行,也可以在
Worker.cs的ExecuteAsync方法里处理参数,但这个场景下用一次性控制台逻辑更合适。
三、改造myWebApp:用System.Diagnostics.Process启动Worker
在MVC的Controller里加一个Action,用来触发启动Worker的逻辑,比如在HomeController里:
using System.Diagnostics; using Microsoft.AspNetCore.Mvc; namespace myWebApp.Controllers { public class HomeController : Controller { public IActionResult Index() { return View(); } public IActionResult LaunchWorker(int num1, int num2, int num3) { // 这里替换成你实际的myWorker可执行文件路径,调试时用相对路径,发布后用绝对路径 string workerExePath = @"..\myWorker\bin\Debug\net6.0\myWorker.exe"; // 根据你的.NET版本调整 // 配置进程启动信息 var startInfo = new ProcessStartInfo { FileName = workerExePath, // 传递参数,也可以用ArgumentList来避免命令行注入风险(更安全) Arguments = $"{num1} {num2} {num3}", UseShellExecute = false, // 后台运行,不弹控制台窗口 CreateNoWindow = true, RedirectStandardOutput = true, // 可选:捕获Worker的输出信息 RedirectStandardError = true // 可选:捕获错误信息 }; // 启动并监控进程 using (var process = Process.Start(startInfo)) { // 读取输出和错误信息(如果需要的话) string output = process.StandardOutput.ReadToEnd(); string errorMsg = process.StandardError.ReadToEnd(); process.WaitForExit(); // 等待Worker执行完成,也可以去掉这句让它后台异步运行 // 把结果传递到视图展示 ViewBag.SuccessOutput = output; ViewBag.ErrorOutput = errorMsg; } return View("WorkerExecutionResult"); } } }
然后创建对应的视图WorkerExecutionResult.cshtml,用来展示执行状态:
@{ ViewData["Title"] = "Worker执行状态"; } <h1>Worker执行状态</h1> @if (!string.IsNullOrEmpty(ViewBag.SuccessOutput)) { <div class="alert alert-success"> <strong>执行成功:</strong>@ViewBag.SuccessOutput </div> } @if (!string.IsNullOrEmpty(ViewBag.ErrorOutput)) { <div class="alert alert-danger"> <strong>执行出错:</strong>@ViewBag.ErrorOutput </div> } <a asp-action="Index" class="btn btn-primary">返回首页</a>
四、重要注意事项要记牢
- 路径问题:一定要确保WebApp能访问到Worker的可执行文件,调试时可以用相对路径,发布后建议把路径配置在
appsettings.json里,避免硬编码。 - 权限问题:WebApp的运行账户需要有执行Worker程序和写入文件的权限,否则会报错。
- 参数安全:如果参数可能包含特殊字符,别直接拼接字符串,用
startInfo.ArgumentList.Add()来逐个添加参数,能避免命令行注入风险,比如:startInfo.ArgumentList.Add(num1.ToString()); startInfo.ArgumentList.Add(num2.ToString()); startInfo.ArgumentList.Add(num3.ToString()); - 异步运行:如果不需要等待Worker执行完成,删掉
process.WaitForExit()即可,但要注意进程管理,避免产生过多无人回收的进程。
五、测试一下效果
- 先编译
myWorker项目,确保生成了可执行文件 - 启动
myWebApp,访问/Home/LaunchWorker?num1=5&num2=10&num3=15 - 去
myWorker的输出目录找result.txt,里面应该会显示“计算结果:三个数字的总和是 30”
这样就完成了从WebApp启动Worker并传递参数的功能啦!
内容的提问来源于stack exchange,提问作者Ahmadou Kassoum
相关产品推荐
相关产品推荐

