在 C# 中启动可执行任务与进程
Starting an executable Task vs Process in C#
我正在用 C# 构建一个客户端实用程序 (Application Upgrader),它会定期检查服务器是否有升级可用,如果可用则下载它,否则它什么都不做。目前,我想到了两种方法——基于流程和基于任务。在这两种方法中,我都从(控制台应用程序的)Main 方法启动升级程序。应该使用这两种方法中的哪一种?
提供了要求 -
- Upgrader 实用程序应该 运行 异步(不阻塞 Main)
- 下载升级后,它会提示用户立即安装或稍后安装
其次,如何在下面的代码中安排从 Main() 定期执行 "upgrader.exe"?
另外,有没有更好的方法来实现这种异步下载的功能?我设想我们在后台看到移动应用程序发生的一种升级,然后提示要求安装。
class Program
{
static async Task Main(string[] args)
{
string filename = @"C:\Users\abc\upgrader.exe";
Console.WriteLine(FiggleFonts.Standard.Render("Hello World"));
Console.WriteLine("About to start the upgrader process now...");
// Approch 1: DirectlyProcess based
//using(Process myprocess = new Process())
//{
// myprocess.StartInfo.FileName = filename;
// myprocess.StartInfo.CreateNoWindow = true;
// myprocess.Start();
//}
// Approach 2: Task based
await RunProcessAsync(filename).ContinueWith(taskres => Console.WriteLine($"taskresult is: {taskres}"));
Console.WriteLine("This code runs after RunProcessAsyncFinishes. Pop up a windows to ask install now or later");
}
static Task<int> RunProcessAsync(string filename)
{
var tcs = new TaskCompletionSource<int>();
var upgraderprocess = new Process
{
StartInfo =
{
FileName = filename
},
EnableRaisingEvents = true
};
upgraderprocess.Exited += (sender, args) =>
{
tcs.SetResult(upgraderprocess.ExitCode);
upgraderprocess.Dispose();
};
upgraderprocess.Start();
return tcs.Task;
}
}
对于你的第一个问题,虽然任务共享相同的内存space并且应该运行在另一个进程下,进程有自己的内存space 并且它们可以 运行 独立于任何其他进程。此功能有起有落。好事是你可以 运行 一个进程并杀死 运行 它在第一位的主进程,第二个进程仍然存在。但不好的是,如果您需要与另一个进程共享某些属性或内存 space,则可能需要一些解决方法。
对于您的第二个问题,您可能会考虑为 Windows 服务器使用 计划任务。或者您可以将此功能注册为服务(最简单的方法是使用TopShelf,https://github.com/Topshelf/Topshelf)并在它为执行创建一些间隔。
看看这 2 个选项,select 最适合您要求的选项。如有任何其他问题,请给我留言。
希望对您有所帮助。
我正在用 C# 构建一个客户端实用程序 (Application Upgrader),它会定期检查服务器是否有升级可用,如果可用则下载它,否则它什么都不做。目前,我想到了两种方法——基于流程和基于任务。在这两种方法中,我都从(控制台应用程序的)Main 方法启动升级程序。应该使用这两种方法中的哪一种? 提供了要求 -
- Upgrader 实用程序应该 运行 异步(不阻塞 Main)
- 下载升级后,它会提示用户立即安装或稍后安装
其次,如何在下面的代码中安排从 Main() 定期执行 "upgrader.exe"? 另外,有没有更好的方法来实现这种异步下载的功能?我设想我们在后台看到移动应用程序发生的一种升级,然后提示要求安装。
class Program
{
static async Task Main(string[] args)
{
string filename = @"C:\Users\abc\upgrader.exe";
Console.WriteLine(FiggleFonts.Standard.Render("Hello World"));
Console.WriteLine("About to start the upgrader process now...");
// Approch 1: DirectlyProcess based
//using(Process myprocess = new Process())
//{
// myprocess.StartInfo.FileName = filename;
// myprocess.StartInfo.CreateNoWindow = true;
// myprocess.Start();
//}
// Approach 2: Task based
await RunProcessAsync(filename).ContinueWith(taskres => Console.WriteLine($"taskresult is: {taskres}"));
Console.WriteLine("This code runs after RunProcessAsyncFinishes. Pop up a windows to ask install now or later");
}
static Task<int> RunProcessAsync(string filename)
{
var tcs = new TaskCompletionSource<int>();
var upgraderprocess = new Process
{
StartInfo =
{
FileName = filename
},
EnableRaisingEvents = true
};
upgraderprocess.Exited += (sender, args) =>
{
tcs.SetResult(upgraderprocess.ExitCode);
upgraderprocess.Dispose();
};
upgraderprocess.Start();
return tcs.Task;
}
}
对于你的第一个问题,虽然任务共享相同的内存space并且应该运行在另一个进程下,进程有自己的内存space 并且它们可以 运行 独立于任何其他进程。此功能有起有落。好事是你可以 运行 一个进程并杀死 运行 它在第一位的主进程,第二个进程仍然存在。但不好的是,如果您需要与另一个进程共享某些属性或内存 space,则可能需要一些解决方法。
对于您的第二个问题,您可能会考虑为 Windows 服务器使用 计划任务。或者您可以将此功能注册为服务(最简单的方法是使用TopShelf,https://github.com/Topshelf/Topshelf)并在它为执行创建一些间隔。
看看这 2 个选项,select 最适合您要求的选项。如有任何其他问题,请给我留言。
希望对您有所帮助。