C# C“Winforms:一个可以控制UI和can的线程”;“睡眠”;没有暂停整个程序。怎么用?
好的 看起来WinForms和线程在同一个程序中是我不容易掌握的东西 我正在尝试用两个图片框(使用一个按钮)和一个文本框制作一个自定义数字上下。是的,我可以使用默认的NumericUpDown表单,但我想制作一个外观不同的表单 我曾尝试使用计时器(System.Windows.Forms.Timer)来实现这一点。问题是,当一个计时器遇到“Thread.Sleep(int)”时,整个程序“进入睡眠状态” 我试过用线。某些类型的线程无法控制UI。然后我试了这个C# C“Winforms:一个可以控制UI和can的线程”;“睡眠”;没有暂停整个程序。怎么用?,c#,winforms,multithreading,C#,Winforms,Multithreading,好的 看起来WinForms和线程在同一个程序中是我不容易掌握的东西 我正在尝试用两个图片框(使用一个按钮)和一个文本框制作一个自定义数字上下。是的,我可以使用默认的NumericUpDown表单,但我想制作一个外观不同的表单 我曾尝试使用计时器(System.Windows.Forms.Timer)来实现这一点。问题是,当一个计时器遇到“Thread.Sleep(int)”时,整个程序“进入睡眠状态” 我试过用线。某些类型的线程无法控制UI。然后我试了这个 private void decla
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;
});
}
结果和我只用定时器时一样
所以,我想让自定义数字上下浮动。但我不能把它弄对。我知道我做错了。我想创建一个线程,它可以控制UI,并且在调用“thread.Sleep(int)”时不会使整个程序暂停
请给我初学者的答案。到目前为止,我还没有找到一个好的答案,可以告诉我正确的方法,也很容易理解。你在寻找这个问题的错误答案。没有线程可以访问UI控件和睡眠而不阻塞UI。只有UI线程可以安全地访问UI控件,如果使UI线程处于睡眠状态,则UI将无响应 恐怕你需要咬紧牙关,学习如何正确地穿线。请注意,睡眠几乎总是错误的方法-尤其是在UI线程中。你甚至没有说你想做什么,但是计时器是一种很好的表达方式,“我想在以后的某个时间点执行一些操作。”有-你应该使用哪一个取决于你想做什么
线程是那些你不能真正捷径的话题之一——你应该考虑读一本或一本详细涵盖它的书。
< P>回答你的实际问题,用这个: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;
});
}
当然,你对正确的事件驱动程序编程的整个心理模型是错误的。你会更好地适应20年前的人们
如果你想在做某事之前等待半秒钟,请将计时器设置为500毫秒,然后退出你的功能。让计时器告诉您何时完成,以便您可以进行下半部分:
// 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;
如果您愿意下载(或等待C#5.0),您可以使用新的
async
和wait
关键字来实现真正优雅的解决方案。1
上面代码中的wait
关键字将在执行延迟任务时将控制权返回到消息循环。任务完成后,执行将恢复到停止的位置。这只是新关键词如此酷的众多原因之一
1请注意,异步CTP使用
TaskEx
而不是Task
WPF是您的选择吗?如果是这样的话,您可以更轻松地自定义数字上下控件,并在不阻塞UI的情况下执行“等待”任务。看起来很简单。我会试试看。。。只要我安装VS2010SP1。这对我来说需要一些时间。这不起作用。当我添加“async”一词时,会出现此错误“找不到与任务相关的类型。是否缺少对“AsyncCtpLibrary.dll”的引用?”。当我添加行“wait Task.Delay(500);”时,出现了另一个错误:“名称'Task'在当前上下文中不存在”。为什么?还有什么吗?考虑到TPL现在是.NET的正式部分,最好更新这个答案。这真的是对这个问题最好最适用的答案了,伊姆霍。
button.Click += delegate { BeginInvoke(new UiUpdate(delegate { Thread.Sleep(500); // Do Stuff After Sleep };)) };
private delegate void UiUpdate();
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;
}
}