C# 如何使用任务闪烁标签
我想要一个扩展方法来闪烁Windows窗体上的标签 所以我写了下面的代码C# 如何使用任务闪烁标签,c#,.net,winforms,C#,.net,Winforms,我想要一个扩展方法来闪烁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 Cancell
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();
}
label1.Blink("Hello World!");
label1.Blink("Hi");
如果我有两个按钮,一个闪烁,一个停止,一切都很好。。。
我的问题是,如果我有一个按钮与以下代码
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();
}
label1.Blink("Hello World!");
label1.Blink("Hi");
在使用Blink方法启动第二个任务之前,我需要一种方法来取消第一个任务…目前的解决方案存在一些问题。首先,取消令牌是静态的,因此它们将在所有闪烁的标签之间共享。另一方面,通过使用任务构造函数、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);
}
}
我不知道为什么,但它不起作用。在我的应用程序中,我有一个场景,同一个标签应该更改其文本并闪烁。这就是重点。按顺序闪烁的停止不会给取消任务的时间。我尝试了Task.WhenAllTasks.ToArray,但没有成功…为什么要将闪烁与设置标签文本混为一谈?闪烁不应设置文本。案子结束了,为什么不呢?这不是重点。。。关键是要以适当的方式取消第一个任务…从Blink方法返回取消令牌,您应该能够取消该任务。哦,还有,从方法中生成取消令牌。摆脱静态实例。如果我扩展Label控件,将CancellationTokenSource作为属性,在Blink方法中取消它,您认为如何?@user3641815:如果您要扩展Label,为什么要使用CTS或Blink方法?为什么不干脆拥有一个IsBlinking酒店呢?我对我想到的解决方案很着迷,没有其他选择,谢谢!