关于正确的worker方法签名,我需要理解以下几点:
Task而不是void for Worker方法是否有意义(如果要同步的话)?Wait()) Worker方法(如果要同步)吗?Worker对象时,Task方法的返回值应该是什么(如果进行同步/异步)?Worker方法完成的工作是长时间运行的CPU/IO绑定工作,那么它应该是什么签名和主体?我应该遵循2.本建议 (如果是混合/异步)吗?Note
尽管使用了cpu绑定代码,但还是可以选择调用io绑定方法的异步版本(sql查询)。所以它可能是同步的,也可能是部分异步的。至于Worker方法中代码的性质。
public class LoopingService
{
private CancellationTokenSource cts;
// ..
void Worker(CancellationToken cancellationToken)
{
while(!cancellationToken.IsCancellationRequested)
{
// mixed, CPU/IO-bound code
try {
// sql query (can be called either as sync/async)
var lastId = documentService.GetLastDocument().Id;
// get next document from a public resource (third-party code, sync)
// can be moved to a web api
var document = thirdPartyDocumentService.GetNextDocument(lastId);
// apply different processors in parallel
var tasksList = new List<Task>();
foreach(var processor in documentService.Processors) {
// each processor checks if it's applicable
// which may include xml-parsing, additional db calls, regexes
// if it's applicable then document data is inserted into the db
var task = new Task(() => processor.Process(document));
tasksList.Add(task);
task.Start();
}
// or
// var tasksList = documentService.ProcessParallel(document);
Task.WaitAll(tasksList.ToArray(), cancellationToken);
}
catch(Exception ex) {
logger.log(ex);
}
}
}
public void Start()
{
this.cts = new CancellationTokenSource();
Task.Run(() => this.Worker(cts.Token));
}
public void Stop()
{
this.cts.Cancel();
this.cts.Dispose();
}
}发布于 2018-07-13 13:47:11
返回任务而不是为Worker方法返回方法有意义吗?
如果Worker是一个真正的异步方法,它应该返回一个Task,以便您能够等待它。如果它只是在后台线程上运行的同步方法,则没有必要从void中更改返回类型,前提是该方法不应该返回任何内容。
当标记为返回
Worker对象时,Task方法的返回值应该是多少?
没什么。如果该方法是异步的,并使用返回类型的async标记为Task,则不应该返回任何值:
async Task Worker(CancellationToken cancellationToken) { ... }注意,除非在方法中实际使用await关键字,否则没有必要将该方法定义为await。
Worker方法的哪些特征和主体应该给出它所完成的工作是长时间运行的CPU/IO绑定工作?我应该遵循这个建议吗?
是的,可能吧。如果出于某种原因,您在同一方法中同时执行异步和同步(CPU绑定)工作,则应该更喜欢使用异步签名,而不是将同步内容包装在Task.Run中。那么您的服务将会是这样的:
public class LoopingService
{
private CancellationTokenSource cts;
async Task Worker(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
await ...
}
}
public async Task Start()
{
this.cts = new CancellationTokenSource();
await this.Worker(cts.Token).ConfigureAwait(false);
}
public void Stop()
{
this.cts.Cancel();
this.cts.Dispose();
}
}理想情况下,您的方法应该是异步的或CPU绑定的,但不能两者兼而有之。
https://stackoverflow.com/questions/51325998
复制相似问题