Reputation: 361
I want to use ManualResetEvent
instead of Thread.Sleep
to prevent my UI from freeing.
This is what I have tried:
private ManualResetEvent manualResetEvent = null;
private void Form1_Load(object sender, EventArgs e)
{
ManualResetEvent manualResetEvent = new ManualResetEvent(false);
}
And after my operation I want to wait 5 seconds:
manualResetEvent.WaitOne(5000);
My problem is that my UI is still freezing ...
Upvotes: 2
Views: 4135
Reputation: 3799
You need to create a dedicated background thread to run the sleep on in order for the UI thread to remain ublocked and free to process its messages.
Doing manualResetEvent.WaitOne(5000);
on the main UI thread will always block it.
The ManualResetEvent is a thread synchronisation primitive, hence is typically used when there are 2 or more threads in action and you want to provide synchronicity between them: E.g. Thread A blocks until some action has occurred in thread B.
Here you only have one. You can run the manualResetEvent.WaitOne(5000);
in another thread (e.g. Task), but you can easily just Sleep(5000) in that task/background thread as the UI thread will remain responsive anyway.
Even better would be not to sleep and wait for an event to fire from the background thread to the UI thread informing that processing is complete.
This may help you also.
Upvotes: 1
Reputation: 1242
Now the situation is more clear.
In this case you may use backgroundworker in example define a backgroundworker in your form.
when timer event id fired you may use
'assume that backgroundworker is named "BBC"
'support cancellation task
BBC.WorkerSupportsCancellation = True
'enable report progress
BBC.WorkerReportsProgress = True
'run it
BBC.RunWorkerAsync()
When it finish in BBC_RunWorkerCompleted or your delegate to the method you can show a message in trhead safe mode.
that's all your from wont freeze, you will be able to use as well your application and so on.I use this method for long tasks or multiple tasks like deletion and so on.You have to set your own method/logic to see if your file has been created into the folder or not.
Upvotes: 3
Reputation: 1242
You can achive your goal in this way.Locked thread is separate one in threadpool and until ti will set manualreset event all code will wait but your ui will not freeze.
Private Sub test1(ByVal obj As Object)
If TypeOf (obj) Is ManualResetEvent Then
Dim _wait = DirectCast(obj, ManualResetEvent)
Thread.Sleep(5000)
_wait.Set()
End If
End Sub
Private Sub TestT_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
MsgBox("Operation started at " & Now)
Dim h As New List(Of ManualResetEvent)
Dim _wait As New ManualResetEvent(False)
h.Add(_wait)
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf test1), _wait)
WaitHandle.WaitAll(h.ToArray)
MsgBox("Operation completed at " & Now)
End Sub
here in c#(translate with online tools check code)
private void test1(object obj)
{
if ((obj) is ManualResetEvent) {
dynamic _wait = (ManualResetEvent)obj;
Thread.Sleep(5000);
_wait.Set();
}
}
private void TestT_Load(System.Object sender, System.EventArgs e)
{
Interaction.MsgBox("Operation started at " + DateAndTime.Now);
List<ManualResetEvent> h = new List<ManualResetEvent>();
ManualResetEvent _wait = new ManualResetEvent(false);
h.Add(_wait);
ThreadPool.QueueUserWorkItem(new WaitCallback(test1), _wait);
WaitHandle.WaitAll(h.ToArray());
Interaction.MsgBox("Operation completed at " + DateAndTime.Now);
}
however I don't understand why you're blocking for X second your interface....
Upvotes: 0
Reputation: 1515
Try to use following:
Task.Run(() => manualResetEvent.WaitOne(5000)).Wait();
Upvotes: -2