在c# WinForms中,我如何在几秒钟内分配标签文本并再次删除它,而不会中断其他代码的执行
本文关键字:删除 执行 代码 其他 文本 中断 分配 WinForms 几秒 钟内 标签 | 更新日期: 2023-09-27 17:54:59
我正在创建一个todolist程序,你可以在其中添加一个任务,当它完成时,你选中一个复选框,点击更新,任务从列表中删除(完成)。
我已经创造了一个游戏化的版本,你每完成一项任务就能获得XP点。我简单地从任务字符串的长度计算XP。总XP然后显示在WinForm的标签文本上。
然后我有了一个想法,我想要显示总XP的标签,显示从一个任务中获得的XP,只是几秒钟,然后再显示总XP。
我只是不知道如何做到这一点,而不让整个代码等待几秒钟。我想它需要在一个单独的线程中运行,我没有经验。
1) XPlabel shows: 1455 XP
2) User completes task
3) XPlabel shows for 2 seconds: +254 XP
4) XPlabel shows: 1709 XP
而其余的代码没有等待这2秒,而是继续运行,做其他任务。比如更新数据存储文本文件
但是,正如我提到的那样,这样做会带来延迟的体验,因为从数据文本文件(我存储任务的地方)写入/删除的其他代码也必须等待几秒钟。在这几秒钟内,整个用户界面将处于暂停状态。
所以…
有一种方法,我可以做到这一点,而代码继续运行?
代码摘录:
//removes checked items
foreach (string item in todolistCheckbox.CheckedItems)
{
string strFilePath = "tododo.data";
string strSearchText = item;
string strOldText;
string n = "";
StreamReader sr = File.OpenText(strFilePath);
while ((strOldText = sr.ReadLine()) != null)
{
if (!strOldText.Equals(strSearchText))
{
n += strOldText + Environment.NewLine;
}
//XP Calculation
xpread();
I WANT --> xplabel.text = xp; --- 2 seconds
int x;
Int32.TryParse(xp, out x);
int buffxp = strOldText.Length * 8 + x;
string xpupd = buffxp.ToString();
//write
xpwrite(xpupd);
xpupdate(xpupd);
levelup(xpupd);
}
sr.Close();
File.WriteAllText(strFilePath, n);
}
/欢呼
您可以使用Task
:
xplabel.Text = "+254";
// 2 second pause
Task.Delay(2000)
// after 2 second continue execution
.ContinueWith(t => { xplabel.Text = "1709"; },
CancellationToken.None,
TaskContinuationOptions.None,
// execution will be in GUI context, i.e. safe
TaskScheduler.FromCurrentSynchronizationContext());
不要忘记using System.Threading;
using System.Threading.Tasks;
您可以使用ThreadPool将其旋转到另一个线程上,并让它管理自己。
ThreadPool.QueueUserWorkItem(new WaitCallback(myFunction), xp);
public void myFunction(object state)
{
int xp = (int)state;
myLabel.Invoke((MethodInvoker)(() => myLabel.SelectedText = xp)); //Thread Safe Label Updater
new System.Threading.ManualResetEvent(false).WaitOne(2000); //Wait 2 Seconds
myLabel.Invoke((MethodInvoker)(() => myLabel.SelectedText = string.Empty)); //Sets the label to empty. Could also be used to put back to totalXP
}
以及您可能需要的任何其他选项。
编辑:请确保您所做的任何线程都包含using System.Threading