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)主UI线程上的代码>将始终阻止它
是一个线程同步原语,因此通常在有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()