重複の可能性:
TPL タスクを中止/キャンセルするにはどうすればよいですか?
実行に時間がかかるメソッドがあるため、結果をコールバックとして返します。私の方法は次のようになります。
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 は多くのスペースを配置します。コードを自由にフォーマットしてください:)