8

Windowsサービスにwhileループがあり、これはx回実行され、ファイルから読み取った後にx回の通話を開始します。今、私が電話を止めるオプションを与えるユーザーインターフェースを作りたいなら、すなわちそれが完了する前でさえwhileループを壊します。どうすればいいですか?

私が関数を持っているとしましょう。

DialCalls(x)
{
  for(int i= 0 ; i<x ; i++)
  {
    // Initiate call
  }
}

アプリケーションでスレッド化を行ったのと同じように、2,3個のDialCalls関数が異なるスレッドで同時に実行される可能性があります。したがって、基本的に、Webページからループを解除するための最良の方法はおそらく何ですか。

4

7 に答える 7

6

タスクキャンセルの使用(.net 4の新機能):

[Fact]
public void StartAndCancel()
{
    var cancellationTokenSource = new CancellationTokenSource();
    var token = cancellationTokenSource.Token;
    var tasks = Enumerable.Repeat(0, 2)
                          .Select(i => Task.Run(() => Dial(token), token))
                          .ToArray(); // start dialing on two threads
    Thread.Sleep(200); // give the tasks time to start
    cancellationTokenSource.Cancel();
    Assert.Throws<AggregateException>(() => Task.WaitAll(tasks));
    Assert.True(tasks.All(t => t.Status == TaskStatus.Canceled));
}

public void Dial(CancellationToken token)
{
    while (true)
    {
        token.ThrowIfCancellationRequested();
        Console.WriteLine("Called from thread {0}", Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(50);
    }
}

http://blogs.msdn.com/b/csharpfaq/archive/2010/07/19/parallel-programming-task-cancellation.aspx タスクは例外を飲み込むので、おそらくIDisposableとして、いくつかのクリーンアップがありますか? タスクの例外について

于 2012-09-28T17:40:13.167 に答える
4

ループ内にifステートメントを記述して、外部イベントのステータスをポーリングできます。

たとえば、次のようなフラグを設定できます。

bool break_out = false;

また、外部イベントでは、break_outフラグをtrueに設定します。

break_out = true;

今あなたのループで、あなたは持つことができます:

DialCalls(x)
{
  for(int i= 0 ; i<x ; i++)
  {
    // Initiate call

    if (break_out) {
        break;
    }
  }
}
于 2012-09-28T17:41:44.963 に答える
3

キャンセルをサポートするイベントを作成します。

public event EventHandler<CancelEventArgs> Call;

サブスクライバーが存在してキャンセルした場合は、電話をかけないでください。

while (true)
{
    var e = new System.ComponentModel.CancelEventArgs();
    if (Call != null)
    {
        Call(this, e);
    }
    if (!e.Cancel)
    {
        // Initiate call
    }
    else
    {
        break;
    }
}
于 2012-09-28T17:43:04.913 に答える
1
while (!_shouldStop) { /* work in progress */ }

またStop()、同じワーカークラスにある必要があるメソッドでは、bool変数をtrueに設定する必要があります。

AutoResetEventまた、(のような)ウェイターがいる場合は、そうである必要があります.Set();

于 2012-09-28T17:45:43.947 に答える
0

いつブレークするかを指示する変数を使用する。

private bool _cancel;

void DialCalls(...)
{
    for (int i=0; i<x; i++)
    {
        ...
        if (_cancel) break;
        ....
    }
}

private void SomeEventHandler(object sender, EventArgs e)
{
    _cancel = true;
}

また

for (int i=0; i<x && !_cancel; i++)
于 2012-09-28T17:43:14.120 に答える
0

揮発性のグローバル変数を持つ

public static volatile bool stop;    
stop=False;

DialCalls(x)
{
  for(int i= 0 ; i<x && !stop ; i++)
  {
    // Initiate call
  }
}

On Button Click => stop =True;
于 2012-09-28T17:43:19.283 に答える
0

グローバル/静的ブール(またはその他の)変数を切り替えるメッセージを受け入れるエンドポイントをサービスに実装し、DialCalls各反復の開始時に内部ループでその変数をチェックします。現在進行中の通話が中断されることはありませんが、通話の途中でサービスが切断されることは望ましくなく、次の通話に移らないでください。これにより、すべてのスレッドでも割り込みが発生します。変数自体がスレッドセーフであることを確認してください(たとえば、volatileキーワードを使用します)。

于 2012-09-28T17:44:30.670 に答える