我需要一个比Thread.Sleep更好的睡眠任务设计,我正在使用Task类。
在我的wpf应用程序中,我运行一个任务,这个任务运行另外几个任务,每个任务首先登录到和互联网网站,在他们登录后,他们需要等待几秒钟,并通知用户他们将继续前进,这是我的问题,因为使用Thread.Sleep我不能报告进展。
有比登录更多的功能,大约是5-6,它们都请求一个Internet资源,在它们之间需要一个睡眠时间,剩余的时间报告发送gui,这个5-6函数都在一个任务中,但是可能有很多任务。
我需要的是让任务等待,但也允许它在剩余的时间内发送更新到GUI。
你对这个问题有什么想法,如何使它变得更好,也许你已经有了一些设计模式来解决这个问题?
我还听说,使用Thread.Sleep是一个糟糕的设计实践。
编辑:没人知道?什么样的自给计时器和线程等着,像腰部,自动发送器,有人吗?
发布于 2011-11-15 12:43:12
忘记使用Thread.Sleep。相反,在后台线程中运行任务,并使用WaitHandle和AutoResetEvent。(链接:WaitHandle/WaitOne / AutoReset)
后台线程可以使用异步委托向UI发送更新,但是调用线程将等待它,直到发生任何一种情况:
1)线程报告它已经使用yourwaithandle.Set()完成了任务;
或
2)等待线程超时(将超时值设置为WaitOne() -method的参数)。
发布于 2011-11-09 10:28:13
解决方案是将其视为异步回调,而不是同步等待。如果您在异步CTP上,正确的方法是:
async item => { await Task.Delay(1000); Process(item); }
这似乎也是DataFlow或Rx的理想用例。
使用反应性扩展:
static void Track(int timeout, int frequency, string item)
{
Observable.Interval(TimeSpan.FromSeconds(frequency)) //produces 0, 1, 2.. with the interval
.Do(i => Console.WriteLine("Working on {0}", item)) // work on item
.TakeUntil(Observable.Timer(TimeSpan.FromSeconds(timeout))) //stop once the timer publishes a value
.Subscribe
(
i => Console.WriteLine("Reporting {0}%", ((double)(i + 1) / timeout * 100)), // the interval reaches OnNext
e => Console.WriteLine("Error!"), // error occured
() => Console.WriteLine("Completed") // observable completed
);
}
在用Track(timeout: 5, frequency: 1, item: "http://example.com/?")
调用它时,产生的输出是:
Working on http://example.com/?
Reporting 20%
Working on http://example.com/?
Reporting 40%
Working on http://example.com/?
Reporting 60%
Working on http://example.com/?
Reporting 80%
Completed
发布于 2011-11-06 20:02:13
与其让单个任务执行所有这六个函数(登录等),不如让每个函数成为一个单独的任务。然后,您可以创建一个按时间排序的优先级队列。当您想要启动这些元任务之一时,将其第一个函数与状态数据(即url、用户id、密码等)一起放入队列中。
当每个函数完成时,它将对要执行的下一个函数进行排队。因此,如果前两个函数是登录函数和get_data函数,则需要:
queue login with state data to execute at DateTime.Now
When login is finished, it queues get_data with the state data and DateTime.Now + 5 seconds (or whatever time)
当最后一个函数执行时,它会在某个地方发布结果。
然后,您可以设置一个计时器,它将以每秒10次轮询队列(或者在队列中添加某些内容时更新定时器的下一个滴答时间)。它可以根据需要启动单个任务。
新的异步CTP可能已经有了这样的东西:“在时间上执行任务”。也许值得一查。
至于报告进度,每个函数都可以在开始时报告进度(即“登录”.“等待5秒才能得到数据”。“获取数据”等)如果需要,可以让计时器线程定期遍历优先级队列,并报告何时执行特定任务。虽然这可能有点过分。
您所听到的是对的:Thread.Sleep
是一个非常糟糕的主意,特别是在您处理线程池线程时。
https://stackoverflow.com/questions/8029685
复制相似问题