2017-02-28 41 views
0

除停止按鈕之外的所有內容均可正常工作。 (按鈕3和按鈕4 OnClick):對多線程應用程序中的按鈕單擊沒有任何影響

我做了一個有四個按鈕的應用程序。

這是一個多線程應用程序。

按鈕1和2將開始產卵線程。

按鈕3和4將分別停止該過程。

但它似乎沒有工作。

這裏是我的代碼:

public partial class Form1: Form 
{ 
    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); 
    CancellationToken token; 

    public Form1() 
    { 
     InitializeComponent(); 
     token = cancellationTokenSource.Token; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     Task t = Task.Run(() => 
     { 
      while (true) 
      { 
       for (int i = 0; i < 100; i++) 
       { 
        System.Threading.Thread.Sleep(1000); 
        Action act =() => textBox1.Text = Convert.ToString(i); 
        textBox1.Invoke(act); 
       } 
       if (token.IsCancellationRequested) 
       { 
        token.ThrowIfCancellationRequested(); 
       } 
      } 
     }, token); 
     } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     //token.Cancel(); 
    } 

    private void button3_Click(object sender, EventArgs e) 
    { 
     Task t1 = Task.Run(() => 
     { 
      while (true) 
      { 
       for (int i = 0; i < 100; i++) 
       { 
        System.Threading.Thread.Sleep(1000); 
        Action act =() => textBox2.Text = Convert.ToString(i); 
        textBox2.Invoke(act); 
       } 
       if (token.IsCancellationRequested) 
       { 
        token.ThrowIfCancellationRequested(); 
       } 
      } 
     }, token); 
    } 

    private void button4_Click(object sender, EventArgs e) 
    { 
     //token.Cancel(); 
    } 
} 

更新

下面是更新後的代碼:

using System; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace MultiThreading_Start_Stop_Counter 
{ 
public partial class Form1 : Form 
{ 
    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); 
    CancellationToken token; 
    CancellationTokenSource cancellationTokenSource1 = new CancellationTokenSource(); 
    CancellationToken token1; 

    public Form1() 
    { 
     InitializeComponent(); 
     token = cancellationTokenSource.Token; 
     token1 = cancellationTokenSource1.Token; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     Task t = Task.Run(() => 
     { 
      for (int i = 0; i < 10; i++) 
      { 
       if (token.IsCancellationRequested) 
       { 
        token.ThrowIfCancellationRequested(); 
       } 
       // your code 
       System.Threading.Thread.Sleep(1000); 
       Action act =() => textBox1.Text = Convert.ToString(i); 
       textBox1.Invoke(act); 
      } 
     }); 
     } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     cancellationTokenSource.Cancel(); 
    } 

    private void button3_Click(object sender, EventArgs e) 
    { 
     Task t1 = Task.Run(() => 
     { 
      for (int i = 0; i < 10; i++) 
      { 
       if (token1.IsCancellationRequested) 
       { 
        token1.ThrowIfCancellationRequested(); 
       } 
       // your code 
       System.Threading.Thread.Sleep(1000); 
       Action act =() => textBox2.Text = Convert.ToString(i); 
       textBox2.Invoke(act); 
      } 
     }); 
    } 

    private void button4_Click(object sender, EventArgs e) 
    { 
     cancellationTokenSource1.Cancel(); 
    } 
} 
} 

現在的任務是消除,但與此異常:

的ty的例外pe'System.OperationCanceledException'發生在mscorlib.dll中,但未在用戶代碼中處理 附加信息:操作已取消。

解決:

使用while循環。謝謝!

+2

你得到一個錯誤,指出錯誤CancellationTokenSource和的CancellationToken?而不是while(true)做類似while(!token.IsCancellationRequested) – Trey

回答

0

檢查是否取消標記應放在裏面的for循環的一部分。

for (int i = 0; i < 100; i++) 
{ 
    if (token.IsCancellationRequested) 
    { 
     token.ThrowIfCancellationRequested(); 
    } 
    System.Threading.Thread.Sleep(1000); 
    Action act =() => textBox1.Text = Convert.ToString(i); 
    textBox1.Invoke(act); 
} 

再加上你拋出OperationCanceledException並且不要捕獲它。

如果你不想處理異常,你可以介紹一些變量while循環,如:

Task t = Task.Run(() => 
     { 
      var run = true; 
      while (run) 
      { 
       for (int i = 0; i < 100; i++) 
       { 
        if (token.IsCancellationRequested) 
        { 
         run = false; 
         break; 
        } 
        //loop code 
       } 
      } 
     }, token); 

BUTTON2應該包含代碼,取消令牌cancellationTokenSource.Cancel();

而你需要的按鈕3和4

0
  • 取消方法屬於CancellationTokenSource,所以你不能把它的CancellationToken
  • 如果(token.IsCancellationRequested)被稱爲只有100秒後,所以也許你只是沒有等待足夠長的更可能是把您在錯誤的地方
0

正是因爲@Roman說,

你應該做一個新的CancellationTokenSource每個CancellationToken,如果令牌在不同的任務要求。

CancellationTokenSource cancellationTokenSource1, cancellationTokenSource2; 
CancellationToken token1, token2; 

讓兩個不同的CancellationTokenSourceCancellationToken

根據您的取消情況,在您的for循環或while循環中使用它們。

for (int i = 0; i < 100; i++) 
{ 
    if (token1.IsCancellationRequested) 
    { 
     token1.ThrowIfCancellationRequested(); 
    } 
    // your code 
    System.Threading.Thread.Sleep(1000); 
    Action act =() => textBox1.Text = Convert.ToString(i); 
    textBox1.Invoke(act); 
} 

或者

while (token1.IsCancellationRequested) 
{ 
} 
相關問題