我想使用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.完成
预期,不会冻结:
答案 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();
}
}
}