2

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 ...

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
user3328870
  • 341
  • 2
  • 7
  • 23
  • If you use any blocking operation on the UI thread, the UI will freeze. Why do you want a 5 second pause, what are you trying to achieve? – Ceilingfish Apr 08 '14 at 12:09
  • Create new file on disk (Wireshark file - Pcap file) and capturing some packets into this files and because this happen fast the Pcap file didn't create yet so i want to wait until this file create – user3328870 Apr 08 '14 at 12:13
  • In that case you need to subscribe for some event which notifies you upon completion. You shouldn't block. Keep in mind that there is no guarantee that operation will finish within 5 seconds! – Sriram Sakthivel Apr 08 '14 at 12:22
  • It's not entirely clear where you are trying to do this capture operation. Is it triggered when the `Form1_Load` callback is fired, or has it already begun by then? – Ceilingfish Apr 08 '14 at 12:22
  • this operation is start every few hours via timer, any idea how to ensure my file created instead of wait 5 seconds ? – user3328870 Apr 08 '14 at 12:24

4 Answers4

3

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.

makemoney2010
  • 1,222
  • 10
  • 11
1

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.

Community
  • 1
  • 1
Jeb
  • 3,689
  • 5
  • 28
  • 45
0

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....

Palak.Maheria
  • 1,497
  • 2
  • 15
  • 32
makemoney2010
  • 1,222
  • 10
  • 11
-2

Try to use following:

Task.Run(() => manualResetEvent.WaitOne(5000)).Wait();
Palak.Maheria
  • 1,497
  • 2
  • 15
  • 32