2017-02-28 40 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) 
{ 
} 
相关问题