简体   繁体   English

C#Winforms:一个可以控制UI并且可以“休眠”而不会暂停整个程序的线程。 怎么样?

[英]C# Winforms: A thread that can control the UI and can “sleep” without pausing the whole program. How?

OK... 好...

Looks like WinForms and Threading in the same program is something that I can't master easily. 在同一个程序中看起来像WinForms和Threading是我无法轻易掌握的东西。

I'm trying to make a custom Numeric Up Down out of two picture boxes (used a buttons) and a text box. 我正在尝试从两个图片框(使用按钮)和文本框中制作自定义数字向上。 Yes, I can use the default NumericUpDown form, but I want to make a different looking one. 是的,我可以使用默认的NumericUpDown表单,但我想做一个不同的表单。

I have tried to do that with timers (System.Windows.Forms.Timer). 我试图用计时器(System.Windows.Forms.Timer)来做到这一点。 The problem is that when one timer meets "Thread.Sleep(int)", the whole program "falls to sleep". 问题是当一个计时器遇到“Thread.Sleep(int)”时,整个程序“陷入睡眠”。

I tried with threads. 我试过线程。 Some types of threads can't control the UI. 某些类型的线程无法控制UI。 Then I tried this 然后我尝试了这个

private void declare_thread()
{
    //some work
    Thread delay = new Thread(new ThreadStart(delay0));
    delay.Start();
    //some more work
}
//other functions
private void delay0()
{
    //delay_for_500ms.WaitOne();
    this.Invoke((ThreadStart)delegate()
    {
    Thread.Sleep(500);
    if (is_mouse_down)
    timer1.Enabled = true;
    });
}

The result was the same as when I used timers only. 结果与我仅使用计时器的结果相同。

So, I want to make custom Numeric Up Down. 所以,我想制作自定义数字向上。 But I can't get it right. 但我无法做到对。 I know I'm doin' it wrong. 我知道我做错了。 I want to make a thread that can control the UI and doesn't make the whole program pause when calling "Thread.Sleep(int)". 我想创建一个可以控制UI的线程,并且在调用“Thread.Sleep(int)”时不会使整个程序暂停。

Please, give me answers for beginners. 请给我初学者的答案。 So far I haven't found a good answer that can show me the right way and it's easy to understand. 到目前为止,我还没有找到一个可以向我展示正确方法的好答案,而且很容易理解。

You're looking for the wrong answer to the problem. 你正在寻找问题的错误答案。 There's no such thing as a thread which can access UI controls and sleep without blocking the UI. 没有一个线程可以访问UI控件睡眠而不会阻止UI。 Only the UI thread can access UI controls safely, and if you make the UI thread sleep, your UI will be unresponsive. 只有UI线程可以安全地访问UI控件,如果您使UI线程处于休眠状态,您的UI将无法响应。

I'm afraid you need to bite the bullet and learn how to perform the threading properly. 我担心你需要咬紧牙关并学习如何正确执行线程。 Note that sleeping is almost always the wrong approach - especially in the UI thread. 请注意,睡眠几乎总是错误的方法 - 尤其是在UI线程中。 You ahven't really said what you're trying to do, but a timer is a good way of saying, "I want to perform some action at a later point in time." 你还没有真正说出你想要做的事情,但计时器是一种很好的方式,“我想在以后的某个时间点执行一些动作。” There are various different timers in .NET - which one you should use will depend on what you're trying to do. .NET中各种不同的计时器 - 你应该使用哪一个取决于你想要做什么。

Threading is one of those topics that you can't really shortcut - you should consider reading a thorough tutorial or a book which covers it in detail. 线程是你不能真正快捷的主题之一 - 你应该考虑阅读一本详尽的教程或一本详细介绍它的书。

To answer your actual question, use this: 要回答您的实际问题,请使用:

private void declare_thread()
{
    //some work
    Thread delay = new Thread(new ThreadStart(delay0));
    delay.Start();
    //some more work
}

//other functions
private void delay0()
{
    //delay_for_500ms.WaitOne();
    Thread.Sleep(500);
    this.Invoke((ThreadStart)delegate()
    {

    if (is_mouse_down)
    timer1.Enabled = true;
    });
}

Of course your whole mental model of proper, event driver programming is wrong. 当然,正确的事件驱动程序编程的整个心理模型是错误的。 You'd fit in better with the old single-task DOS people 20 years ago. 20年前,你可以更好地适应旧的单任务DOS人员。

If you want to wait half a second before doing something, set a timer for 500ms and exit your function. 如果您想在做某事之前等待半秒钟,请将计时器设置为500毫秒并退出​​您的功能。 Let the timer tell you when it's done so you can do the second half: 让计时器告诉你何时完成,这样你就可以完成下半场:

// on the main thread

// la la la doing work
// wait 500ms
var tmr=new Timer{Interval=500};
tmr.Tick+=(s,e)=>{/*action .5sec later*/ btn.Enabled=false; tmr.Enabled=false;};
tmr.Enabled=true;

// and quit
return;

If you are willing to download the Async CTP (or wait for C# 5.0) you can use the new async and await keywords to make for a really elegant solution. 如果您愿意下载Async CTP (或等待C#5.0),您可以使用新的asyncawait关键字来制作一个非常优雅的解决方案。 1 1

public class YourForm : Form
{
  private async void UpPictureBox_Click(object sender, EventArgs args)
  {
    await Task.Delay(500);
    timer1.Enabled = is_mouse_down;
  }

  private async void DownPictureBox_Click(object sender, EventArgs args)
  {
    await Task.Delay(500);
    timer1.Enabled = is_mouse_down;
  }
}

The await keyword in the code above will yield control back to the message loop while the delay task is executing. 上面的代码中的await关键字将在延迟任务执行时将控制权返回给消息循环。 Execution will pick back up where it left off upon completion of that task. 执行将在完成该任务后从中断处继续。 This is but one among many reasons why the new keywords are so wicked cool. 这只是新关键词如此邪恶酷炫的众多原因之一。


1 Note that the Async CTP uses TaskEx instead of Task . 1 请注意,Async CTP使用TaskEx而不是Task

button.Click += delegate { BeginInvoke(new UiUpdate(delegate { Thread.Sleep(500); // Do Stuff After Sleep };)) };

private delegate void UiUpdate();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C#等待而不使线程睡眠和冷冻程序。 - C# Wait without making the thread sleep and freezing the program. 在不暂停UI的情况下休眠运行 - Sleep the running without pausing the UI 如何在C#中拍摄Winforms控件/窗体的屏幕截图? - How can I take a screenshot of a Winforms control/form in C#? C# Thread.Sleep(ms) 冻结 UI,我无法使用替代选项 - C# Thread.Sleep(ms) Freezes UI and I can't use Alternative Options 使用C#/ WPF(非WinForms!)时如何让显示器进入睡眠状态 - How can I put the monitor to sleep when using C#/WPF (Not WinForms!) C#:在不锁定UI线程的情况下,如何让方法等待2秒才能返回? - C#: How can I have a method wait 2 seconds before it returns, without locking up the UI thread? 如何在WinForms C#中创建Metro ui切换开关控件? - how to create a Metro ui toggle switch control in winforms c#? 与Thread.Sleep相比,在C#中暂停线程可获得更准确的时间-最佳方法是什么? - Pausing the thread in C# for more accurate time than Thread.Sleep - what would be the best approach? 我写了一个C#程序。 我可以把它放在我的WP7手机上吗? - I've written a C# program. Can I put it on my WP7 phone? 如何在C#中的UI线程上延迟运行代码? - How can I delay running code on the UI thread in C#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM