使用CancellationTokenSource对象需要与Task对象进行配合使用,Task会对当前运行的状态进行控制(这个不用我们关心是如何控制的)。而CancellationTokenSource则是外部对Task的控制,如取消、定时取消。
CancellationTokenSource 中暂未提供复位操作,因此当调用Cancle 之后,若再次调用,需重新初使化对象。
Demo:
CancellationTokenSource tokenSource = new CancellationTokenSource();
Task[] tasks = new Task[2];
string url = "www.baidu.com";
bool isconn = true;
tasks[0] = Task.Run<bool>(() =>
{
Ping ping = new Ping();
try
{
PingReply pr;
pr = ping.Send(url);
Thread.Sleep(4000);
if (pr.Status != IPStatus.Success)
{
isconn = false;
}
if (tokenSource.Token.IsCancellationRequested)
{
isconn = false;
}
this.Invoke(new Action(() =>
{
this.errorMessage.Visibility = Visibility.Hidden;
this.message.Visibility = Visibility.Hidden;
this.errorMessage.Visibility = Visibility.Hidden;
this.btnOnOff.IsEnabled = true;
this.cmbSerialPort.IsEnabled = true;
tokenSource.Cancel();
}));
return isconn;
}
catch (Exception ex)
{
isconn = false;
}
return isconn;
}, tokenSource.Token);
tasks[1] = Task.Run(() =>
{
timer.Interval = new TimeSpan(0, 0, 0, 1);
timer.Tick += (s, oe) =>
{
Seconds--;
if (Seconds < 0)
{
timer.Stop();
Seconds = 6;
this.lberrormessage.Content = "服务器连接失败";
return;
}
ShowTime();
if (tokenSource.Token.IsCancellationRequested)
{
timer.Stop();
Seconds = 6;
return;
}
lberrormessage.Content = "正在连接服务器......" + Seconds;
if (Seconds < 0)
{
lberrormessage.Content = "服务器连接失败!";
timer.Stop();
Seconds = 6;
tokenSource.Cancel();
}
};
//timer.Start();
//isconn = false;
//Seconds = 6;
}, tokenSource.Token);
代码中定义了两个task,这两个task的结果是互相影响的。如果task1返回为true,则task2停止执行。如果task2返回为true,则task1停止。另外一定要注意task1和task2的先后顺序,这个就要看具体的需求而定了。总之,代码实现了两个task之间的通信。task的运行结果,影响task之间的执行。
注:我这是在TabControl中编写的应用,发现首次登陆的时候可以成功执行,但是在不同tab之间切换之后就不能正确的执行了。现在也不知道为啥!有高手遇到过吗?跪求解答。