2016-06-01 14 views
3

メソッドを呼び出す方法はありますか?メソッドが完了するまでに時間がかかる場合、メソッドはキャンセルされ、呼び出しメソッドに?私はスレッドでこれを行うことができると思うが、スレッドが必要ない場合はどうするのだろうか?メソッドを呼び出してキャンセルし、呼び出しに時間がかかりすぎる場合は呼び出しメソッドに戻ります。

参考までに、私がkill/stop/abortする必要のある方法は、CorelDraw 15 APIを呼び出すことです。これにより、CorelDrawのインスタンスが開き、このメソッドで繰り返し不可能なエラーが発生しました。つまり、同じ画像を2回処理することができます.1回はフリーズまたはエラー、もう1回は処理しません。

私が使用している問題の現在の解決策は、Process.Start(firstAppExecutablePath)を実行し、テキストファイルの変数をチェックし、変数が10分後に変更されない場合、.Kill();が呼び出されます。プロセス。可能であれば、このソリューションを避けたいと思います。それは.Kill();を実行しているので、物事がどのように近づいているのか非常に乱雑ですが、一般的には問題は生じません。

+4

それは、ねじいない場合は、実行中のスレッドがあなたの方法を実行しているので、タイムアウトをチェックする方法はありません。 「それは長すぎますか?」を確認するものはありません。 – dman2306

+4

api asyncはありますか?これは、CancellationTokenのためのものです。 – Crowcoder

+1

方法は何ですか? – Luaan

答えて

0

関数内からのタイムアウトを確認するのが大丈夫でない限り、スレッディングは絶対に必要です。だからここのスレッドで最小限のアプローチです:

private static bool ExecuteWithTimeout(TimeSpan timeout, Action action) 
{ 
    Thread x = new Thread(() => { action(); }); 
    x.Start(); 

    if (!x.Join(timeout)) 
    { 
     x.Abort(); //Or Interrupt instead, if you use e.g. Thread.Sleep in your method 
     return false; 
    } 

    return true; 
} 
+3

他のスレッドを中止することはお勧めできません。他のスレッドが現在静的コンストラクタを実行している場合、そのプロセス内でそのコンストラクタを持つ型のオブジェクトを構築することは決してできません。 [ドキュメント](https://msdn.microsoft.com/en-us/library/ty8d3wta(v = vs.110).aspx#Anchor_2)の注記を参照してください。 –

+0

@Cameron 'x.Abort()'はそれを "キャンセル"せず、スレッドは "楽しいことを続けています"私はそれが信じることが難しいと思う... –

+0

@ LasseV.Karlsenうん、それは悪いです。だから(もし私たちがコードOPのどんなkinを取り消そうとしているのか分かっていれば)CancellationTokenを持つもの、あるいは少なくともAbortの代わりにInterruptが望ましいでしょう。 –

1

内蔵されていない、いない、任意のコードを中断するので、それはCライブラリ関数を呼び出すの真ん中にいた場合(つまり、サポートされていないものを(安全に行うことができませんグローバルロックを取得してリリースする必要があるのは例外です)。

しかし、あなたはこのようなサポートを自分で書くことができます。私は潜在的な問題の完全な新しい次元があるので、絶対に必要でない限り、ミックスにスレッドを追加しません。

例:

void Caller() 
{ 
    int result; 
    if (TryDoSomething(out result, 100)) { 
     System.Console.WriteLine("Result: {0}", result); 
    } 
} 

bool TryDoSomething(out int result, int timeoutMillis) 
{ 
    var sw = Stopwatch.StartNew(); 
    result = 0x12345678; 
    for (int i = 0; i != 100000000; ++i) { 
     if (sw.ElapsedMilliseconds > timeoutMillis) 
      return false; 
     result += i/(result % 43) + (i % 19); 
    } 
    return true; 
} 
+0

これは本当に質問に答えていないようです。 OPは、1つのメソッド呼び出しをタイムアウトにしたいのに対し、あなたがやっていることは、ある一定の期間、短い1回の操作を繰り返すことです。私の見解では同じものではありません(OPは異なると思われるかもしれませんが)。 @Chrisが同意した。 – Chris

+0

メソッドが実行された時間をチェックするためにメソッドを変更できると仮定しています。ブロックされたIO操作をタイムアウトしようとしたらどうなりますか? – dman2306

+0

'TryDoSomething' *は*単一のメソッド;-)ほとんどのメソッドは、戦略的な位置でのタイムアウトのチェックを装備することができます。ループはほんの一例でした。そして、はい、これはOPの場合ではないことが判明して以来、ターゲットメソッドのコントロールを前提としています。私は一般的なケースの答えを残します。 I/Oおよび他のOSレベルの操作は、十分な労力でタイムアウトに統合できるノンブロッキングバージョンを持つ傾向があります。 – Cameron

関連する問題