Правильный выход из консольного приложения .net, использующего задачи .NET 4.0 - PullRequest
3 голосов
/ 07 мая 2011

У меня есть консольное приложение, которое по сути выглядит так

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


public classs DoStuffService
{
    public void Start()
    {
        Task.Factory.StartNew(() => { LongRunningOperation() });
    }

    private void LongRunningOperation()
    {
        // stuff
    }    
}

Каков наилучший способ в наши дни убедиться, что мое консольное приложение не завершается до завершения LongRunningOperation(), а также позволяет мне получать уведомление в консольном приложении (например, для ведения журнала), что LongRunningOperation() полный.

Ответы [ 3 ]

3 голосов
/ 07 мая 2011

вызов 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");
    }
}
1 голос
/ 07 мая 2011

В дополнение к ответу Cheeso вам понадобится обработать Console.CancelKeyPress, чтобы вы могли отобразить сообщение о занятости и установить e.Cancel = True.

Вы ничего не можете сделать, чтобы они не убили процесс, но вы можете по крайней мере справиться с Ctrl + C и Ctrl + Break.

0 голосов

Существует похожий поток 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;
    }
}
...