我知道在C#和Windows窗体中有Thread.Sleep
、System.Windows.Forms.Timer
和Monitor.Wait
,但我似乎无法弄清楚如何等待X秒,然后做其他事情-而不锁定线程。
我有一个带有按钮的表单。单击按钮时,计时器将启动并等待5秒。5秒后,表单上的其他控件将变为绿色。当使用Thread.Sleep
时,整个应用程序将在5秒内无响应-那么我如何“5秒后执行某项操作”呢?
我知道在C#和Windows窗体中有Thread.Sleep
、System.Windows.Forms.Timer
和Monitor.Wait
,但我似乎无法弄清楚如何等待X秒,然后做其他事情-而不锁定线程。
我有一个带有按钮的表单。单击按钮时,计时器将启动并等待5秒。5秒后,表单上的其他控件将变为绿色。当使用Thread.Sleep
时,整个应用程序将在5秒内无响应-那么我如何“5秒后执行某项操作”呢?
7条答案
按热度按时间anhgbhbe1#
(转抄自Ben作为评论)
只需使用System. Windows. Forms. Timer。2将计时器设置为5秒,并处理Tick事件。3当事件触发时,执行该操作。
...并在执行工作之前禁用计时器(IsEnabled=false),以便抑制秒。
Tick事件 * 可能 * 在另一个无法修改GUI的线程上执行,您可以捕获此事件:
为了完整起见:使用async/await,可以很容易地延迟执行某些操作(一次性,永远不重复调用):
有关详细信息,请参阅MSDN中的“异步和等待”。
更完整:根据您的框架,您很有可能拥有可以在内部处理调用的
DispatcherTimer
类(WPF变体)。iaqfqrcu2#
你有没有试
您可以像这样使用:
参考:https://msdn.microsoft.com/en-us/library/hh194873(v=vs.110).aspx
xeufq47z3#
您可以启动执行操作的异步任务:
要传入间隔,只需将其存储在一个变量中:
aiqt4smr4#
您可以等待UI线程按照您希望的方式工作。
如果您使用的是.Net Framework 4.5或更高版本,则可以使用
Task.Run
代替Task.Factory.StartNew
,如下所示。chy5wohz5#
你看错了。点击按钮,它会启动一个间隔为x秒的计时器。当时间到了,eventhandler就会执行任务。
你不想发生什么。
当x秒过去时。
当任务正在执行时?
例如,如果你不希望在延迟和任务完成之前按钮被点击,那么在按钮点击处理程序中禁用它,并在任务完成时启用它。
如果您所需要的只是在任务开始前延迟5秒,那么您应该将开始延迟传递给任务,让它来处理。
wxclj1h56#
你的应用程序挂起因为你是调用这5秒睡眠/等待在这主要UI线程.把这睡眠/等待/whatever动作在一个分开的线程(实际上System.Windows.Forms.Timer应该会为你做这件事),当它完成的时候,调用一个动作,把一些控件变成绿色。记得选中InvokeRequired。(SetText可以从另一个线程调用,如果是,则调用将改为在文本框打开的主UI线程上调用):
我从here中获取了这个示例(非常值得一读!)。
zyfwsgd67#
Tick事件可能在另一个线程上执行,该线程无法修改您的gui,您可以捕获此...
医生可不是这么说的。
您在示例代码中使用的是System.Windows.Forms.Timer。
这是一个 Forms.Timer。
根据C#文档,计时器事件在UI线程上引发。
此Windows计时器是为单线程环境设计的,其中UI线程用于执行处理。它要求用户代码具有可用的UI消息泵,并且始终从同一线程操作...
另请参见stackoverflow post here