Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用ManualResetEvent而不冻结我的UI_C#_.net_Manualresetevent - Fatal编程技术网

C# 如何使用ManualResetEvent而不冻结我的UI

C# 如何使用ManualResetEvent而不冻结我的UI,c#,.net,manualresetevent,C#,.net,Manualresetevent,我想使用ManualResetEvent而不是Thread.Sleep来阻止UI释放 这就是我尝试过的: private ManualResetEvent manualResetEvent = null; private void Form1_Load(object sender, EventArgs e) { ManualResetEvent manualResetEvent = new ManualResetEvent(false); } 手术后我想等5秒钟: manualRes

我想使用
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);
我的问题是我的UI仍然冻结…

请尝试使用以下方法:

Task.Run(() => manualResetEvent.WaitOne(5000)).Wait();

您可以通过这种方式实现您的目标。锁定的线程在线程池中是独立的,直到ti设置manualreset事件,所有代码都将等待,但您的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(对象obj)
{
如果((obj)为手动重置事件){
动态等待=(手动重置事件)obj;
睡眠(5000);
_等等,Set();
}
}
私有void TestT_加载(System.Object sender,System.EventArgs e)
{
MsgBox(“操作开始于”+DateAndTime.Now);
列表h=新列表();
ManualResetEvent _wait=新的ManualResetEvent(错误);
h、 添加(_wait);
QueueUserWorkItem(新WaitCallback(test1),\u wait);
WaitHandle.WaitAll(h.ToArray());
MsgBox(“操作在“+DateAndTime.Now”完成);
}

但是,我不明白为什么要将界面阻塞X秒……

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

执行
manualResetEvent.WaitOne(5000)将始终阻止它

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

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

更好的方法是不要睡觉,等待UI线程发出处理完成的通知


也可能对你有所帮助。

现在情况更清楚了

在这种情况下,您可以在示例中使用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安全模式下显示消息


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

OP是否要使用ManualResetEvent如果在UI线程上使用任何阻止操作,UI将冻结。为什么要暂停5秒,你想实现什么?在磁盘上创建新文件(Wireshark文件-Pcap文件)并将一些数据包捕获到此文件中,因为这发生得很快,Pcap文件尚未创建,所以我想等待此文件创建。在这种情况下,你需要订阅一些事件,在完成时通知你。你不应该挡住。请记住,不能保证操作将在5秒内完成!还不完全清楚您要在哪里执行此捕获操作。它是在触发
Form1\u Load
回调时触发的,还是已经开始了?此操作通过计时器每隔几个小时启动一次,您知道如何确保创建我的文件而不是等待5秒吗?
'assume that backgroundworker is named "BBC"
'support cancellation task
 BBC.WorkerSupportsCancellation = True
'enable report progress 
 BBC.WorkerReportsProgress = True
'run it        
 BBC.RunWorkerAsync()