我正在开发一个向客户端公开 Web 服务的简单服务器。一些请求可能需要很长时间才能完成,并且在逻辑上分为多个步骤。对于此类请求,需要在执行过程中报告进度。此外,新请求可能会在前一个请求完成之前发起,并且要求两者同时执行(除非某些系统特定的限制)。
我正在考虑让服务器向其客户端返回一个 TaskId,并让客户端使用 TaskId 跟踪请求的进度。我认为这是一个很好的方法,剩下的问题是如何管理任务。
从未使用过 TPL,我认为这将是解决此问题的好方法。事实上,它允许我同时运行多个任务,而无需手动管理线程。我什至可以使用 ContinueWith 相对轻松地创建多步骤任务。
不过,我想不出一个跟踪任务进度的好方法。我意识到,当我的请求包含一个“步骤”时,该步骤必须合作报告其状态。这是我现在更愿意避免的事情。但是,当请求包含多个步骤时,我想知道当前正在执行哪个步骤并相应地报告进度。我能想出的唯一方法是非常烦人:
Task<int> firstTask = new Task( () => { DoFirstStep(); return 3.14; } );
firstTask.
ContinueWith<int>( task => { UpdateProgress("50%"); return task.Result; } ).
ContinueWith<string>( task => { DoSecondStep(task.Result); return "blah"; }.
ContinueWith<string>( task => { UpdateProgress("100%"); return task.Result; } ).
甚至这也不完美,因为我希望任务存储自己的进度,而不是让 UpdateProgress 更新某个已知位置。此外,它还有一个明显的缺点,即在添加新步骤时必须更改很多地方(因为现在进度是 33%、66%、100% 而不是 50%、100%)。
有没有人有好的解决方案?
谢谢!