2

我想使用ManualResetEvent而不是Thread.Sleep防止我的 UI 被释放。

这是我尝试过的:

private ManualResetEvent manualResetEvent = null;

private void Form1_Load(object sender, EventArgs e)
{
    ManualResetEvent manualResetEvent = new ManualResetEvent(false);
}

手术后我想等待 5 秒钟:

manualResetEvent.WaitOne(5000);

我的问题是我的用户界面仍然冻结...

4

4 回答 4

3

现在情况更清楚了。

在这种情况下,您可以在示例中使用 backgroundworker 在表单中定义一个 backgroundworker。

当计时器事件 id 被触发时,您可以使用

'assume that backgroundworker is named "BBC"
'support cancellation task
 BBC.WorkerSupportsCancellation = True
'enable report progress 
 BBC.WorkerReportsProgress = True
'run it        
 BBC.RunWorkerAsync()

当它在 BBC_RunWorkerCompleted 或您的方法中完成时,您可以在 trhead 安全模式下显示一条消息。

这就是你的全部,不会冻结,你也可以使用你的应用程序等等。我将这种方法用于长任务或删除等多项任务。你必须设置自己的方法/逻辑,看看你的文件是否已创建到文件夹中。

于 2014-04-08T13:13:56.627 回答
1

您需要创建一个专用的后台线程来运行睡眠,以使 UI 线程保持未阻塞状态并自由处理其消息。

manualResetEvent.WaitOne(5000);在主 UI 线程上执行将始终阻止它。

ManualResetEvent是线程同步原语,因此通常在有 2 个或更多线程在运行并且您希望在它们之间提供同步性时使用:例如,线程 A 阻塞,直到线程 B 中发生某些操作

在这里你只有一个。您可以manualResetEvent.WaitOne(5000);在另一个线程(例如Task)中运行,但您可以轻松地在该任务/后台线程中只 Sleep(5000) ,因为 UI 线程无论如何都会保持响应。

更好的是不要休眠并等待事件从后台线程触发到通知处理完成的 UI 线程。

也可能对您有所帮助。

于 2014-04-08T12:34:33.677 回答
0

您可以通过这种方式实现您的目标。锁定的线程在线程池中是独立的,直到 ti 设置手动重置事件,所有代码都将等待,但您的 ui 不会冻结。

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

在这里用c#(用在线工具检查代码翻译)

 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);
}

但是我不明白你为什么要阻止 X 秒你的界面....

于 2014-04-08T12:27:42.403 回答
-2

尝试使用以下内容:

Task.Run(() => manualResetEvent.WaitOne(5000)).Wait();
于 2014-04-08T12:07:58.783 回答