I'd like to pause for a file update (can take a few seconds) using Thread.Sleep loop that checks every second for timestamp change. However, the app freezes completely during the sleep loop and can't even refresh the display.
I looked into the following (simplified) code which doesn't freeze the program. But the program reaches the end (prints "Done") before the Worker function ends - wait for the func to complete (print "end" before "done"). Unremarked the last line, to wait for the func's end, freezes the app.
Is there a better way to wait for file change without freezing the app? If not, how to wait for a lengthy function to complete without freezing the app AND waiting for the func to finish before commencing with the main code?
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();
output with the last line remarked:
output with last line unremarked: (app freezes, then): 1. Start 2. End 3. Done
expected, without freezing:
As I mentioned in comments the right way would be to use async/await. The code will look like this:
private async Task Worker()
{
Print("start");
await Task.Delay(5000);
Print("end");
}
main:
public async void DoSomething()
{
await Worker();
Print("Done");
}
If you want to use ThreadPool directly. Base on platform you may need to provide a Dispatcher to Worker method so it call a method to execute in initial thread.
I like waiting with Semaphores. Check out the overloaded method 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();
}
}
}
Assuming you are working with Winforms, one solution is this:
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();
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.