正确退出使用 .NET 4.0 任务的 .net 控制台应用程序

本文关键字:任务 net 控制台 应用程序 退出 NET | 更新日期: 2023-09-27 17:55:34

我有一个控制台应用程序,基本上看起来像这样

class Program
{
    static void Main(string[] args)
    {
        DoStuffService svc = new DoStuffService();
        svc.Start();
    }
}

class DoStuffService
{
    public void Start()
    {
        Task.Factory.StartNew(() => { LongRunningOperation() });
    }
    private void LongRunningOperation()
    {
        // stuff
    }    
}

如今,确保我的控制台应用程序在LongRunningOperation()完成之前不会退出的最佳方法是什么,并且还允许我在控制台应用程序中收到LongRunningOperation()已完成的通知(例如用于日志记录目的)。

正确退出使用 .NET 4.0 任务的 .net 控制台应用程序

在任务上调用Wait()。 例如:

class Program
{
    static void Main(string[] args)
    {
        DoStuffService svc = new DoStuffService();
        svc.Start();
        // stuff...
        svc.DelayTilDone();
    }
}

public class DoStuffService
{
    Task _t;
    public void Start()
    {
        _t = Task.Factory.StartNew(() => { LongRunningOperation(); });
    }
    public void DelayTilDone()
    {
        if (_t==null) return;
        _t.Wait();
    }
    private void LongRunningOperation()
    {
        System.Threading.Thread.Sleep(6000);
        System.Console.WriteLine("LRO done");
    }
}

除了 Cheeso 的答案之外,您还需要处理Console.CancelKeyPress,以便您可以显示忙消息并设置e.Cancel = True

您无法阻止它们终止进程,但您至少可以处理 Ctrl+C 和 Ctrl+Break。

有一个类似的线程 C# 多线程控制台应用程序 - 控制台在线程完成之前退出

您可以简单地返回已启动的任务并对其Wait()ContinueWith()

using System.Diagnostics;
using System.Threading.Tasks;
class Program
{
  static void Main(string[] args)
  {
    DoStuffService svc = new DoStuffService();
    svc.Start().Wait();//bool res = svc.Start() 
    Trace.WriteLine("333333333333333");
  }
}
public class DoStuffService
{
  public Task Start()
  {
    return Task.Factory.StartNew
      (() =>
      {
        Trace.WriteLine("111111111");
        LongRunningOperation(); ;
      });
  }
  private void LongRunningOperation()
  {
    System.Threading.Thread.Sleep(3000);
    Trace.WriteLine("2222222222");
  }
}

任务将阻塞父线程直到完成,如果访问其 Result 属性,因此:

using System.Diagnostics;
using System.Threading.Tasks;
class Program
{
   static void Main(string[] args)
   {
     DoStuffService svc = new DoStuffService();
     svc.Start();//bool res = svc.Start() 
     Trace.WriteLine("333333333333333");
   }
}
public class DoStuffService
{
   public Task<bool> MyTask;
   public bool Start()
   {
      MyTask = Task.Factory.StartNew<bool>
        (() =>
        {
          Trace.WriteLine("111111111");
          return LongRunningOperation();;
        });
      return MyTask.Result;
    }
    private bool LongRunningOperation()
    {
      System.Threading.Thread.Sleep(3000);
      Trace.WriteLine("2222222222");
      return true;
    }
}