我有一个 WCF Rest 服务,它公开一个 Web 方法,该方法应该启动一个长时间运行的进程,然后立即返回一个表示可用于跟踪任务状态的任务的 ID。
[WebGet]
public Task<Guid> LongRunningProcess()
{
var taskId = new Guid();
var task = Task.Factory.StartNew(() =>
{
//Perform long running task
}
task.ContinueWith(task =>
{
//Send a notification to the client that the task has completed.
}
return taskId;
}
我的问题是,这是正确的做法吗?还是有更好、更轻量级的方法?
最佳答案
我的理解是,如果您的工作受 CPU 限制,那么最好同步执行工作。使用您的方法,请求将被停放并且原始请求线程将被释放,但随后将工作移交给另一个线程,并且在该线程完成之前请求不会完成。您也可以在原始线程中完成这项工作。
如果您在那里有一些 IO,那么使该异步 IO 不使用线程是有意义的,它会释放您的请求线程来处理其他请求,从而提高您的可扩展性。
更新
我认为您采用的方法很好,但考虑到您使用的是 .NET 4.5,我会使用 async-await
,因为它会产生更简单的代码。然后我会使用 IO 操作的异步 API 并等待
它的结果。例如:
[WebGet]
public async Task<Guid> LongRunningProcess()
{
var taskId = new Guid();
// IO bound operation
var dbResult = await readFromDbAsync();
// IO bound operation
var dbResult = await readFromDbAsync();
// CPU bound?
generateReport(dbResult);
// IO bound operation
await sendNotification();
return taskId;
}
如果你不熟悉 async-await
,我已经写了一个介绍 here .
关于c# - WCF Rest 服务中的后台工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28758601/