我有一个方法需要一些时间来执行,因此我将结果作为回调返回。我的方法看起来像:
public static void DoWork( Action<object> onCompleteCallBack)
{
Task.Factory.StartNew( () => {
// Do work
onCompleteCallBack(someResult);
});
}
现在我希望能够在用户不想等待的情况下停止执行该方法。结果这就是我的成果:
static void Main ( string[] args )
{
var cancelMethod = DoWork( x =>
{
// method completed
Console.Write( x.ToString() );
});
Thread.Sleep( 5000 ); // some time passes
// then user decides to abort method
cancelMethod();
Console.Read();
}
static Action DoWork ( Action<object> onCompleteCallBack )
{
bool stopExecuting = false;
Task.Factory.StartNew( () =>
{
for ( var i = 0 ; i < 100000 ; i++ )
{
Thread.Sleep( 1 );
if ( stopExecuting )
{
onCompleteCallBack( "Method aborted!" );
return;
}
}
onCompleteCallBack( "Method completed successfully" );
} );
return () => { stopExecuting = true; };
}
什么是更合适的方法来中止方法的执行?
感谢您的回答。我现在记得取消令牌的事情。令牌难以记住。我想我会用这种方法:
static void Main ( string[ ] args )
{
Action abortTask;
DoWork( methodCompleted, out abortTask );
Thread.Sleep( 5000 ); // some time passes then user decides to abort method
// cancel execution of method
abortTask( );
Console.Read( );
}
static void methodCompleted ( object msg )
{
Console.Write( msg.ToString( ) );
}
static void DoWork ( Action<object> onCompleteCallBack, out Action abortThisTask )
{
bool stopExecuting = false;
abortThisTask = ( ) => { stopExecuting = true; };
Task.Factory.StartNew( ( ) =>
{
for ( var i = 0 ; i < 100000 ; i++ )
{
Thread.Sleep( 1 );
if ( stopExecuting )
{
onCompleteCallBack( "Method aborted!" );
return;
}
}
onCompleteCallBack( "Method completed successfully" );
} );
}
// Overloaded method
static void DoWork ( Action<object> onCompleteCallBack )
{
Action abortTask;
DoWork( onCompleteCallBack ,out abortTask );
}
使用你们在这个问题的答案上提出的方法与这种方法相比会更好吗?我更喜欢这种方法。我认为它比取消令牌更容易阅读。
PS。 我的Visual Studio放置了很多空间。随意格式化代码:)
答案 0 :(得分:3)
尝试使用取消令牌,在任务中指定它的功能 http://blogs.msdn.com/b/csharpfaq/archive/2010/07/19/parallel-programming-task-cancellation.aspx
CancellationTokenSource tokenSource = new CancellationTokenSource();
Task.Factory.StartNew( () => {
// Do work
onCompleteCallBack(someResult);
}, tokenSource.Token);
private void cancel_Click(object sender, RoutedEventArgs e)
{
tokenSource.Cancel();
}
答案 1 :(得分:1)
查看CancellationToken和Albahari's guide以安全取消线程
答案 2 :(得分:1)
StartNew()方法的重载接受CancellationToken。这是一个例子:http://msdn.microsoft.com/en-us/library/dd997396.aspx。基础是您创建然后将此标记传递给您的方法(或从父线程引用它;它是线程安全的)。然后,您的并行方法必须在方便的时候(如在循环内)检查令牌是否表明任务已被取消。如果是这样,它会优雅地退出。
答案 3 :(得分:1)
任务允许您传入CancellationToken
。您可以调用ct.Cancel()以设置取消标志。在您的实际执行逻辑中,您可以在某些“检查点”添加检查,以检查if (ct.IsCancellationRequested)
并从那里返回方法,或者调用ct.ThrowIfCancellationRequested()
。
答案 4 :(得分:0)
http://msdn.microsoft.com/en-us/library/dd537607(v=vs.100).aspx可能是个好地方。取决于你的目标。