2010-08-02 2 views
9

У меня есть консольное приложение, и я хочу, чтобы он дождался появления какого-либо события. Но он выполняет код и выходит:Создание консольного приложения ведет себя как приложение Windows

static void Main(string[] args) 
{ 
    var someObjectInstance = new SomeObject(); 
    someObjectInstance.SomeEvent += SomeEventHandler; 
} 

static void SomeEventHandler() 
{ 
    //Some logic 
} 

Я хочу, чтобы мое приложение вести себя как приложение Windows, где

Application.Run(new Form1()); 

называется и цикл обработки сообщений выполняется.

Но мне не нужна ни петля сообщений, ни какая-либо форма. Так что это выглядит как накладные расходы. Есть ли более легкий способ достичь моей цели?

+2

Что * * аспект поведения в Windows Forms приложение вы действительно ищете? Что собирается поднять это событие? –

+0

Я хочу, чтобы можно было ожидать какого-либо события, а затем выйти из приложения вручную. WinForms реализует аналогичное поведение по методу Application.Run. Это событие ConnectionLost, созданное классом IPC на основе сокетов. – SiberianGuy

ответ

18

Во-первых, если SomeObject не собирается поднимать событие в отдельном потоке, это не будет работать без какой-либо форме обработки в SomeObject. Однако, если он разработан таким образом, это довольно просто.

Очень эффективный способ обработки это просто ждать на WaitHandle:

private static ManualResetEvent waitHandle = new ManualResetEvent(false); 
static void Main(string[] args) 
{ 
    var someObjectInstance = new SomeObject(); 
    someObjectInstance.SomeEvent += SomeEventHandler; 
    waitHandle.WaitOne(); // Will block until event occurs 
} 

static void SomeEventHandler() 
{ 
    //some logic 
    waitHandle.Set(); // Will allow Main() to continue, exiting the program 
} 
+0

В каком пространстве имен находится «ManualResetEvent»? – ArtOfCode

+0

@ArtOfCode System.Threading: https://msdn.microsoft.com/en-us/library/system.threading.manualresetevent%28v=vs.110%29.aspx Хотя я бы порекомендовал 'ManualResetEventSlim' сегодня ... –

+0

Хех. Не волнуйся; С тех пор я нашел другой способ сделать это, поэтому я фактически не буду использовать это. – ArtOfCode

2

Добавить

Console.ReadLine(); после прикрепить EventHandler.

Например ..

class Program 
{ 
    static void Main(string[] args) 
    { 
     System.IO.FileSystemWatcher watcher = new System.IO.FileSystemWatcher(@"c:\", "*.txt"); 
     watcher.Created += new System.IO.FileSystemEventHandler(watcher_Created); 
     watcher.EnableRaisingEvents = true; 
     Console.ReadLine(); 
    } 

    static void watcher_Created(object sender, System.IO.FileSystemEventArgs e) 
    { 
     Console.WriteLine(string.Format("{0} was created at {1:hh:mm:ss}", e.FullPath, DateTime.Now)); 
    } 
} 
+1

Это приведет к тому, что приложение Console будет вечно вечно зависеть, если кто-то не введет в консоль ... Не уверен, что это подходящее поведение здесь, так как оно не имеет никакого отношения к ожиданию (внешнего) события. –

+0

Отлично подходит для тестирования ... так здорово для производственного кода. –

+0

в производстве Я бы использовал сервис для этого конкретного примера. Но это работает очень хорошо. –

-1

EDIT: К сожалению, я был неправильным, и это не будет работать, потому что Application не определен для консольного приложения (Спасибо, Reed Copsey).

Это должно сделать трюк, хотя в зависимости от того, как вы выбрали режим сна, вы можете закончить загрузку процессора. Я чувствую, что должен быть более безопасный способ сделать это?

while (true) 
{ 
    Application.DoEvents(); 
    Thread.Sleep(this.SleepTime); 
} 

+1

Это будет работать только в том случае, если у вас есть насос сообщений Windows Forms, который никогда не должен находиться в консольном приложении ... «Приложение» определено только в приложениях Windows Forms. Кроме того, спать, как это, вероятно, не лучший подход, в любом случае. –

Смежные вопросы