按钮无法点击,当Thread.Sleep时

5

我知道当执行Thread.Sleep时,我的GUI上的按钮是无法点击的。

那么还有其他方法可以延迟代码流程但仍能在GUI上点击按钮吗?

例如现在,在我的代码执行Thread.Sleep(10000); 并且在这10秒内我无法单击button1事件,有没有办法使我仍然可以在这10秒内单击button1事件呢?

        private void displaydata_event2(object sender, EventArgs e)
    {
        txt_data.AppendText(in_data + "\n");
        string inStr;
        inStr = in_data;

        //MessageBox.Show(inStr.Length.ToString());

        if (inStr.Length == 12)
        {
            int indexOfSpace = inStr.IndexOf(' ');
            string Patient = inStr.Substring(indexOfSpace + 1);

            int rx = 0;
            int selected = 0;

            txtData1.Text = Patient;

            rx = Convert.ToInt16(Patient);
            selected = Convert.ToInt16(txt_pnorec.Text);

            if (rx != selected)
            {
                MessageBox.Show("Please check patient settings");
            }
        }
        else if (inStr.Length == 24)
        {
            label2.Text = "Patient is not selected!";
            label2.BackColor = Color.Red;
        }
        else if (inStr.Length == 10)
        {
            int indexOfSpace = inStr.IndexOf(':');
            string Temp = inStr.Substring(indexOfSpace + 1);

            txtData2.Text = Temp;

            double tempflo;
            tempflo = Convert.ToDouble(Temp);

            if (tempflo > 20)
            {
                lbl_temp.Text = "Fever";
                lbl_temp.BackColor = Color.Red;
            }
        }
        else if (inStr.Length == 9)
        {
            int indexOfSpace = inStr.IndexOf(':');
            string ECG = inStr.Substring(indexOfSpace + 1);

            txtData3.Text = ECG;
        }
        else if (inStr.Length == 19 || inStr.Length == 20)
        {
            int indexOfSpace = inStr.IndexOf(':');
            string Systolic = inStr.Substring(indexOfSpace + 1);

            txtData4.Text = Systolic;
        }
        else if (inStr.Length == 21 || inStr.Length == 22)
        {
            int indexOfSpace = inStr.IndexOf(':');
            string Diastolic = inStr.Substring(indexOfSpace + 1);

            txtData5.Text = Diastolic;
        }
        else if (inStr.Length == 16)
        {
            int indexOfSpace = inStr.IndexOf(':');
            string Pulse = inStr.Substring(indexOfSpace + 1);

            txtData6.Text = Pulse;
        }

        else if (inStr.Length == 23 || inStr.Length == 17 || inStr.Length == 27 || inStr.Length == 30 || inStr.Length == 35 || inStr.Length == 29)
        {
            lbl_bp.Text = inStr;//to display status of BP (Normal,prehypotension etc)

            string bp;

            bp = inStr;

            if (bp.Length == 23 || bp.Length == 27 || bp.Length == 31 || bp.Length == 35 || bp.Length == 30)
            {
                lbl_bp.BackColor = Color.Red;
            }
            else if (bp.Length == 17)
            {
                lbl_bp.BackColor = Color.LightGray;
            }
        }

        else if (inStr.Length == 32 || inStr.Length == 25 || inStr.Length == 34 || inStr.Length == 33 || inStr.Length == 26 || inStr.Length == 31)
        {
            int indexOfSpace = inStr.IndexOf(':');
            string Acc = inStr.Substring(indexOfSpace + 1);

            txtData7.Text = Acc;

            string test = inStr;

            if (test.Length == 25 || test.Length == 34 || test.Length == 33 || test.Length == 26)
            {
                label21.Text = "Check on patient!";
                label21.BackColor = Color.Red;
            }
            else if (test.Length == 32)
            {
                label21.Text = "";
                label21.BackColor = Color.LightGray;
            }
        }

        else
        {

        }

         if (txtData1.Text != "" && txtData2.Text != "" && txtData3.Text != "" && txtData4.Text != "" && txtData5.Text != "" && txtData6.Text != "" && txtData7.Text != "")
        {
            try
            {
                connection2.Open();
                OleDbCommand command2 = new OleDbCommand();
                command2.Connection = connection2;
                command2.CommandText = "insert into MedicalRecord (PatientNumber,FirstName,LastName,IC,Temperature,ECG,Systolic,Diastolic,Pulse) values('" + txt_pnorec.Text + "','" + txt_fnamerec.Text + "','" + txt_lnamerec.Text + "','" + txt_icrec.Text + "','" + txtData2.Text + "','" + txtData3.Text + "','" + txtData4.Text + "','" + txtData5.Text + "','" + txtData6.Text + "')";

                command2.ExecuteNonQuery();
                MessageBox.Show("Info Stored");
                connection2.Close();

                txtData1.Text = "";
                txtData2.Text = "";
                txtData3.Text = "";
                txtData4.Text = "";
                txtData5.Text = "";
                txtData6.Text = "";
                txtData7.Text = "";

                Thread.Sleep(interval);
                MessageBox.Show("Start");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex);
            }
            txtData1.Text = "";
            txtData2.Text = "";
            txtData3.Text = "";
            txtData4.Text = "";
            txtData5.Text = "";
            txtData6.Text = "";
            txtData7.Text = "";  
        }
    }

提前感谢你。


1
将Thread.Sleep和相关操作放在不同的线程上运行。 - Darren Young
2
你是否在延迟 UI 线程?如果您将线程分离并延迟该线程,则 UI 线程将保持响应。 - eX0du5
你有相关的代码可以展示吗? - Hjalmar Z
嗨,Hjalmar,我已经添加了代码。 - Nic
4个回答

4
有多种方法可以实现这一点。一个例子是使用带有延迟的任务:
Task.Delay(10000).ContinueWith(x => 
{
    //Place the code you want delayed here.
});

另一个例子是使用专为此目的设计的 "BackgroundWorker"。详情请见这里

2

@Gusdor:谢谢,说得好。我已经添加了一些描述。在我写下答案的时候,这个问题还没有代码。只是想展示一个方向。 - CharithJ
@CharithJ 我认为你还应该提到异步/等待只出现在 .Net Framework 版本 4.5 中,因此它不能用于其他版本的 .Net Framework。 - Fabjan

2

您可以使用异步和等待

以下是一个结合GUI的好教程: https://www.youtube.com/watch?v=MCW_eJA2FeY

您需要将函数声明为async

public async void Foo()
{
    ...
}

那么您可以使用:

await Task.Delay(10000);

它将为整个Delay发布GUI,您可以在Delay等待时使用您的GUI。


0
你可以使用 Windows.Forms.Timer 来延迟执行某些操作,而不会冻结 UI 线程。将你的代码拆分为两部分:1. 延迟前;2. 延迟后。
public partial class form1 : Form
{
   // i used namespace to ensure that we use 'correct' Timer and we do not 
   // confuse it with System.Timers.Timer or System.Threading.Timer
   System.Windows.Forms.Timer tmrDelay;

   void SomeMethodWithDelay()
   {
       // code before delay here
       tmrDelay.Enabled = true;
       tmrDelay.Tick += Timer_Tick;
   }

   private void Timer_Tick(object sender, EventArgs e)
   {
       Thread.Sleep(5000);

       // your code here

       // disables timer to stop it
       tmrDelay.Enabled = false;
   }
}

使用计时器的好处在于它是一个本地的Windows表单工具,专门设计用来解决这类问题。然而,您仍然可以使用现代化的东西,比如Tasks,例如:Task.Factory.StartNew(() => { Thread.Sleep(5000); // your method logic here });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接