首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >等待任务的时间,并报告进度

等待任务的时间,并报告进度
EN

Stack Overflow用户
提问于 2011-11-06 19:17:21
回答 4查看 847关注 0票数 8

我需要一个比Thread.Sleep更好的睡眠任务设计,我正在使用Task类。

在我的wpf应用程序中,我运行一个任务,这个任务运行另外几个任务,每个任务首先登录到和互联网网站,在他们登录后,他们需要等待几秒钟,并通知用户他们将继续前进,这是我的问题,因为使用Thread.Sleep我不能报告进展。

有比登录更多的功能,大约是5-6,它们都请求一个Internet资源,在它们之间需要一个睡眠时间,剩余的时间报告发送gui,这个5-6函数都在一个任务中,但是可能有很多任务。

我需要的是让任务等待,但也允许它在剩余的时间内发送更新到GUI。

你对这个问题有什么想法,如何使它变得更好,也许你已经有了一些设计模式来解决这个问题?

我还听说,使用Thread.Sleep是一个糟糕的设计实践。

编辑:没人知道?什么样的自给计时器和线程等着,像腰部,自动发送器,有人吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-11-15 12:43:12

忘记使用Thread.Sleep。相反,在后台线程中运行任务,并使用WaitHandle和AutoResetEvent。(链接:WaitHandle/WaitOne / AutoReset)

后台线程可以使用异步委托向UI发送更新,但是调用线程将等待它,直到发生任何一种情况:

1)线程报告它已经使用yourwaithandle.Set()完成了任务;

2)等待线程超时(将超时值设置为WaitOne() -method的参数)。

票数 1
EN

Stack Overflow用户

发布于 2011-11-09 10:28:13

解决方案是将其视为异步回调,而不是同步等待。如果您在异步CTP上,正确的方法是:

async item => { await Task.Delay(1000); Process(item); }

这似乎也是DataFlow或Rx的理想用例。

使用反应性扩展:

代码语言:javascript
运行
复制
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/?")调用它时,产生的输出是:

代码语言:javascript
运行
复制
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
票数 6
EN

Stack Overflow用户

发布于 2011-11-06 20:02:13

与其让单个任务执行所有这六个函数(登录等),不如让每个函数成为一个单独的任务。然后,您可以创建一个按时间排序的优先级队列。当您想要启动这些元任务之一时,将其第一个函数与状态数据(即url、用户id、密码等)一起放入队列中。

当每个函数完成时,它将对要执行的下一个函数进行排队。因此,如果前两个函数是登录函数和get_data函数,则需要:

代码语言:javascript
运行
复制
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是一个非常糟糕的主意,特别是在您处理线程池线程时。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8029685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档