作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在设计一个API,该API公开可取消的Task
,并希望确保自己设计正确。是否存在用于公开Task
的标准模式(也许类似于APM BeginXxx/EndXxx模式)?有什么建议可以改善吗?参见MyAPI.Run
Test2
是否演示了并行运行许多MyAPI.Run
任务的最佳方法?
public static class MyAPI
{
public static Task<MyResult> Run( CancellationToken token ) {
// lazily create Task, so as to include the specified CancellationToken
return new Task<MyResult>( MyPrivateAsyncMethod, token, token );
}
private static MyResult MyPrivateAsyncMethod( object state ) {
CancellationToken ct = (CancellationToken)state;
ct.ThrowIfCancellationRequested();
return new MyResult();
}
}
public static class TestMyAPI
{
// User can start the Task directly
public static void Test1() {
CancellationTokenSource cts = new CancellationTokenSource();
MyAPI.Run( cts.Token )
.ContinueWith( task => Console.WriteLine( task.Result.ToString() ) )
.Start();
}
// User must wrap in new Tasks to get Parent/Child relationship
public static void Test2() {
CancellationTokenSource cts = new CancellationTokenSource();
Task.Factory.StartNew( () =>
{
var childTasks = new[] {
Task.Factory.StartNew<MyResult>( () => MyAPI.Run( cts.Token ).Result, cts.Token, TaskCreationOptions.AttachedToParent, TaskScheduler.Default ),
Task.Factory.StartNew<MyResult>( () => MyAPI.Run( cts.Token ).Result, cts.Token, TaskCreationOptions.AttachedToParent, TaskScheduler.Default )
};
Task.Factory
.ContinueWhenAll<MyResult>( childTasks, tasks => { foreach( var task in tasks ) task.ToString(); } )
.Start();
}, cts.Token );
}
}
最佳答案
我会考虑更改您的实现中的几个问题。
首先,此方法:
public static Task<MyResult> Run( CancellationToken token ) {
// lazily create Task, so as to include the specified CancellationToken
return new Task<MyResult>( MyPrivateAsyncMethod, token, token );
}
Task
或
Task<T>
的API的约定是返回“热门”任务。这意味着您应将API设计为始终返回已在运行的任务。
MyAPI.Run( cts.Token )
.ContinueWith( task => Console.WriteLine( task.Result.ToString() ) )
.Start();
Task<MyResult> original = MyAPI.Run( cts.Token );
Task second = original.ContinueWith( task => Console.WriteLine( task.Result.ToString() ) );
second.Start();
MyAPI.Run( cts.Token )
.ContinueWith( task => Console.WriteLine( task.Result.ToString() ) );
Task.Factory.StartNew
,让它查看
MyAPI.Run
,但是永远不要在内部的任务上实际调用
Start
。因此,这些任务将永远不会开始也永远不会完成。
Task
或
Task<T>
的例程具有带
Async
后缀的名称。在这种情况下,它将是
MyAPI.RunAsync
。这将使您的代码看起来像将在下一版.NET中出现的框架代码。
Does Test2 demonstrate the best way to run many MyAPI.Run tasks in parallel?
Run
方法返回正在运行的任务,这将变得更加简单:
public static void Test2() {
CancellationTokenSource cts = new CancellationTokenSource();
var task1 = MyAPI.RunAsync(cts.Token);
var task2 = MyAPI.RunAsync(cts.Token);
Task.Factory.ContinueWhenAll<MyResult>(
new[] { task1, task2 },
tasks => {
foreach( var task in tasks ) task.ToString();
},
cts.Token);
}
关于multithreading - 公开可取消的任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8331937/
我们构建了一个基于 Netty/NIO 的服务,我正在考虑将该服务部署到我们的生产环境中。我们部署服务的标准方式是作为 WAR,部署在 Tomcat 中。 当我在这里提出相同的方法时,我得到了“不应该
我是一名优秀的程序员,十分优秀!