如何在不冻结的情况下等待并等待功能完成

时间:2019-06-06 12:33:10

标签: c# threadpool

我想使用Thread.Sleep循环暂停文件更新(可能需要几秒钟),该循环每秒检查一次时间戳更改。但是,该应用在睡眠循环期间会完全冻结,甚至无法刷新显示。

我查看了以下(简化的)代码,该代码不会冻结程序。但是程序在Worker函数结束之前到达末尾(打印“完成”)-等待功能完成(在“完成”之前打印“结束”)。等待功能结束,未注释最后一行,将冻结应用程序。

有没有更好的方法来等待文件更改而不冻结应用程序?如果不是,那么如何在不冻结应用程序的情况下等待冗长的功能完成,并在开始使用主代码之前等待功能完成?

private static ManualResetEvent resetEvent = new ManualResetEvent(false);

private void Worker(object ignored)
{
    Print("start");
    Thread.Sleep(5000);
    Print("end")
    resetEvent.Set();
}

Main:
ThreadPool.QueueUserWorkItem(new WaitCallback(Worker));
Print("Done");
//resetEvent.WaitOne();

最后一行标记为输出的

  1. 完成
  2. 开始
  3. 结束

最后一行未标记的输出: (然后,应用程序冻结):  1.开始  2.结束  3.完成

预期,不会冻结:

  1. 开始
  2. 结束
  3. 完成

3 个答案:

答案 0 :(得分:0)

正如我在评论中提到的,正确的方法是使用async / await。该代码将如下所示:

private async Task Worker()
{
    Print("start");
    await Task.Delay(5000);
    Print("end");
}

主要:

public async void DoSomething()
{
    await Worker();
    Print("Done");
}

如果您想直接使用ThreadPool。基于平台,您可能需要提供一个Dispatcher to Worker方法,以便它调用在初始线程中执行的方法。

答案 1 :(得分:0)

我喜欢等待信号量。检查重载的方法WaitOne。

using System;
using System.Threading;

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            Semaphore mutex = new Semaphore(0, 1);
            Thread t = new Thread(() => {
                Console.WriteLine("Hello from another thread");
                Console.ReadLine();
                mutex.Release();
            });
            t.Start();
            while (!mutex.WaitOne(1000))
                Console.WriteLine("Waiting " + 1 + " sec");
            Console.WriteLine("Hello from main thread");
            Console.ReadLine();
        }
    }
}

答案 2 :(得分:-1)

假设您正在使用Winforms,一种解决方案是:

 class Foo
 {
   bool spin;
   void Worker()
   {      
       Print("start");
       ///Do job
       Print("end")

      spin=false;
   }
   void mainMethod()
   {    
        spin = true;
        ThreadPool.QueueUserWorkItem(new WaitCallback(Worker));
        while(spin)
        {
             Thread.Sleep(500);
             Application.DoEvents(); 
        }
   }
 }
相关问题