Как ждать события во втором потоке - PullRequest
1 голос
/ 30 июля 2009

Рассмотрим следующий код в классе с именем Worker

    FileSystemWatcher watcher = new FileSystemWatcher();
    public void Run()
    {
        watcher.Path = @"c:\queue";
        watcher.Created += new FileSystemEventHandler(watcher_Created);
        watcher.EnableRaisingEvents = true;
    }

Теперь вот что я хотел бы сделать с Работником, но, очевидно, это не сработает.

        Worker worker = new Worker();
        Thread thread = new Thread(worker.Run);
        thread.Start();
        Console.ReadLine(); // something else more interesting would go here.

Причина в том, что метод Run завершается, а не входит в какой-то цикл обработки событий. Как мне запустить цикл событий? (Я думаю, что я ищу что-то вроде Application.Run)

Ответы [ 4 ]

2 голосов
/ 30 июля 2009

Не проверено, но ваш цикл обработки событий, если вы хотите, чтобы он выполнялся в потоке, выглядел бы примерно так:

private bool running = true;
private AutoResetEvent waiter = new AutoResetEvent(false);

public void Run()
{
    FileSystemWatcher watcher = new FileSystemWatcher("C:\\");
    FileSystemEventArgs changes = null;

    watcher.Changed +=
        (object sender, FileSystemEventArgs e) => {
            changes = e;
            waiter.Set();
        };

    watcher.EnableRaisingEvents = true;

    while (running)
    {
        waiter.WaitOne();
        if (!running) break;

        Console.WriteLine("Path: {0}, Type: {1}",
                changes.FullPath, changes.ChangeType);
    }

    Console.WriteLine("Thread complete");
}

public void Stop()
{
    running = false;
    waiter.Set();
}

Вы поместите этот код в класс и запустите его в отдельном потоке (если хотите). Если вы хотите, чтобы ваш основной поток ожидал завершения создаваемого потока (хотя зачем в этом случае создавать поток?), То вы можете использовать метод Thread.Join .

1 голос
/ 30 июля 2009

Вытащено из MSDN

Worker worker = new Worker();
Thread thread = new ThreadStart(worker.Run);
thread.Start();
// Not sure if you need this while
while (!oThread.IsAlive);
oThread.Join();
Console.ReadLine();
0 голосов
/ 30 июля 2009

Не могли бы вы не дать методу Run () завершиться, пока приложение не будет закрыто? Может быть, больше похоже на: (извините, но я связываю это с памятью, а не с IDE, поэтому она может быть не идеальной):

public void Run()
{
    watcher.Path = @"C:\queue";
    watcher.Created += new FileSystemEventHandler(watcher_Created);
    watcher.EnableRaisingEvents = true;

    try
    {
        while(true)
            Thread.Sleep();
    }
    catch(ThreadAbortedException)
    {
        return;
    }
}

и бегун:

Worker worker = new Worker();
Thread thread = new Thread(worker.Run);
thread.Start();
Console.ReadLine(); // something else more interesting would go here.
thread.Abort(); // do when ready to close the app.

Если подумать, почему вы начинаете новую тему для этого? Почему бы просто:

watcher.Path = @"C:\queue";
watcher.Created += new FileSystemEventHandler(watcher_Created);
watcher.EnableRaisingEvents = true;
Console.ReadLine(); // something else more interesting would go here.

Или поместите ваш FileSystemWatcher в переменную, которая не выйдет из области видимости (в основной форме, если приложение WinForms, или в любом другом классе, имеющем метод Main (), если приложение консоли).

Или здесь происходит что-то еще, что не показано?

0 голосов
/ 30 июля 2009

BackgroundWorker, при использовании с RunAsync (), запустит вашу логику в отдельном потоке.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...