在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);
                }

/欢呼

在c# WinForms中,我如何在几秒钟内分配标签文本并再次删除它,而不会中断其他代码的执行

您可以使用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