如何使用Task闪烁标签
本文关键字:标签 闪烁 Task 何使用 | 更新日期: 2024-04-23 15:30:53
我想要一个扩展方法来闪烁Windows窗体上的标签。。。
所以我写了以下代码。。。
private static ConcurrentBag<Task> Tasks = new ConcurrentBag<Task>();
private static CancellationTokenSource cts = null;
public static void Blink(this Label label, string text)
{
cts = new CancellationTokenSource();
Task task = new Task(async () =>
{
label.Invoke((Action)(() =>
{
label.Text = text;
label.Visible = true;
}));
while (true)
{
label.Invoke((Action)(() => { label.Visible = !label.Visible; }));
if (cts.IsCancellationRequested)
{
break;
}
await Task.Delay(600);
}
label.Invoke((Action)(() => { label.Visible = false; }));
},cts.Token);
Tasks.Add(task);
task.Start();
}
还有一些停止的代码。。。
public static void Stop(this Label label)
{
if (cts != null)
{
cts.Cancel();
}
}
如果我有两个按钮,一个带"闪烁",一个带有"停止",一切都很好。。。我的问题是,如果我有一个带有以下代码的按钮。。。
label1.Blink("Hello World!");
label1.Blink("Hi");
在使用Blink方法开始第二个任务之前,我需要一种方法来取消第一个任务。。。
目前的解决方案存在一些问题。首先,取消令牌是static
,因此它们将在所有闪烁标签之间共享。另一方面,由于使用了任务构造函数Start
和Control.Invoke
,代码过于复杂。
一个简单得多的方法看起来像:
public static Tuple<Task, CancellationTokenSource> Blink(this Label label)
{
var cts = new CancellationTokenSource();
var task = BlinkAsync(label, cts.Token);
return Tuple.Create(task, cts);
}
private static Task BlinkAsync(Label label, CancellationToken cancellationToken)
{
label.Visible = true;
while (true)
{
label.Visible = !label.Visible;
cancellationToken.ThrowIfCancellationRequested();
await Task.Delay(600);
}
}
用法:
var runningBlink = label.Blink();
...
runningBlink.Item2.Cancel(); // to stop