Mik*_*liy 13 .net c# asynchronous task-parallel-library async-ctp
我的原始方法如下:
string DoSomeWork();
Run Code Online (Sandbox Code Playgroud)
方法DoSomeWork在其他线程上启动一些工作并返回执行ID(只是随机字符串).稍后我可以通过给定的执行ID查询结果.重点是在作业完成之前使执行ID可用.
现在我想更改签名以返回Task,因此用户可以等待.
Task DoSomeWork();
Run Code Online (Sandbox Code Playgroud)
同时我仍然需要返回执行ID(例如用于跟踪),我看到几个选项.首先是if out参数,第二个是返回带有执行ID和任务的元组(在C#中看起来不是最好的选项),第三个是我真正想要问的.
如果我将创建将从Task类派生的类,该怎么办:
public class ExtendedTask : Task
{
public string ExecutionID {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
这看起来不错吗?或者最好决定其他选择?
PS在BCL中有一些派生自Task类.
更新,似乎我无法定义这个明确的enouthg.但是我需要在作业完成之前访问ExecutionID,因此我无法使用Task.Result.
Jon*_*eet 13
我个人不会延伸 Task<T>,我会改编.这样您就不必担心任何只返回的API Task<T>- 您可以将任务包装起来.你可以拥有一个暴露底层任务的属性,而对于C#5异步目的,你可以在你自己的类型上实现awaiter模式 - 但是我觉得创建你自己的派生类型可能弊大于利.尽管如此,这主要是一种直觉.
另一种选择是反过来:将你的额外状态存储在Task.AsyncState财产中; 毕竟,这就是它的用途.这样,您可以轻松地传递任务,而不会丢失它在逻辑上属于的执行上下文.
Ree*_*sey 11
我建议使用Task<T>,因为它允许您"嵌入"任务结果中的其他信息.
例如,在您的情况下,有类似的东西可能是有意义的:
class ExecutionResult
{
public int ExecutionID { get; set; }
public string Result { get; set; }
// ...
}
public Task<ExecutionResult> DoSomeWork()
{
return Task.Factory.StartNew( () =>
{
// Replace with real work, etc...
return new ExecutionResult { ExecutionID = 0, Result = "Foo" };
});
}
Run Code Online (Sandbox Code Playgroud)
编辑以回应评论:
如果您需要"之前"任务完成的数据,并且为了其他目的而尝试访问它,我建议创建一个包含Task和其他数据的类,并返回它,即:
class ExecutionResult
{
public int ExecutionID { get; private set; }
public Task<string> Result { get; private set; }
// ... Add constructor, etc...
}
public ExecutionResult DoSomeWork()
{
var task = Task.Factory.StartNew( () =>
{
// Replace with real work, etc...
return "Foo";
});
return new ExecutionResult(1, task); // Make the result from the int + Task<string>
}
Run Code Online (Sandbox Code Playgroud)
这仍然可以让您访问有关您的流程和Task/的信息Task<T>.
| 归档时间: |
|
| 查看次数: |
4839 次 |
| 最近记录: |