我想使用ManualResetEvent
代替Thread.Sleep
来阻止我的用户界面免费使用。
这就是我的尝试:
private ManualResetEvent manualResetEvent = null;
private void Form1_Load(object sender, EventArgs e)
{
ManualResetEvent manualResetEvent = new ManualResetEvent(false);
}
在我的手术后我想等5秒钟:
manualResetEvent.WaitOne(5000);
我的问题是我的用户界面仍在冻结...
答案 0 :(得分: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安全模式下显示一条消息。
这一切都是你不会冻结的,你也可以使用你的应用程序等等。我将这个方法用于长任务或删除等多个任务。你必须设置自己的方法/逻辑查看您的文件是否已创建到文件夹中。
答案 1 :(得分:1)
您需要创建一个专用的后台线程来运行睡眠,以便UI线程保持畅通无阻并可以自由处理其消息。
在主UI线程上执行manualResetEvent.WaitOne(5000);
将始终阻止它。
ManualResetEvent是线程同步原语,因此通常在有2个或更多线程在运行时使用,并且您希望在它们之间提供同步性:例如。线程A阻塞直到线程B中发生某些操作。
这里你只有一个。您可以在另一个帖子中运行manualResetEvent.WaitOne(5000);
(例如Task),但您可以轻松地在该任务/后台线程中休眠(5000),因为UI线程无论如何都会保持响应。
更好的方法是不要睡觉并等待event to fire from the background thread到UI线程,告知处理已完成。
This也可以为您提供帮助。
答案 2 :(得分:0)
你可以用这种方式实现目标。锁定线程在线程池中是独立的,直到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(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.
答案 3 :(得分:-2)
尝试使用以下内容:
Task.Run(() => manualResetEvent.WaitOne(5000)).Wait();