Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当我使用线程调用另一个窗体并显示它时,组件(标签)无法正常工作_C#_Multithreading_Visual Studio_Invoke - Fatal编程技术网

C# 当我使用线程调用另一个窗体并显示它时,组件(标签)无法正常工作

C# 当我使用线程调用另一个窗体并显示它时,组件(标签)无法正常工作,c#,multithreading,visual-studio,invoke,C#,Multithreading,Visual Studio,Invoke,因此,为了学习如何使用线程,我制作了一个小程序,它应该接收名称并将它们存储在一个列表中,然后以另一种形式一个接一个地显示名称。 下面是代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.

因此,为了学习如何使用线程,我制作了一个小程序,它应该接收名称并将它们存储在一个列表中,然后以另一种形式一个接一个地显示名称。 下面是代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;

namespace ListingThread
{
public partial class Form1 : Form
{
    public Thread t;
    public static int ShowNo = 0;
    public Form1()
    {
        InitializeComponent();
        GlobalForm = new Form();
        GlobalForm.Show();
        GlobalForm.Hide();
        t = new Thread(ShowList);
    }
    public Form GlobalForm;
    public static List<string> Names = new List<string>();
    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void btnAddName_Click(object sender, EventArgs e)
    {
        AddName(txtName.Text);
        txtName.Text = null;
    }
    public void AddName(string x)
    {
        Names.Add(x);
    }

    private void btnShow_Click(object sender, EventArgs e)
    {
        Showw();
    }
    public void Showw()
    {
        t.Start();
    }
    public void ShowList()
    {
        if (ShowNo < Names.Capacity)
        {

            GlobalForm.Invoke((MethodInvoker)delegate ()
            {
                CustomMessageBox Msg = new CustomMessageBox();
                try { Msg.lblName.Text = Names[ShowNo];
                }
                catch
                {
                    t.Abort();
                }
                Msg.Show();
                Thread.Sleep(500);
                Msg.Close();
                ShowNo++;
                ShowList();
            });
        }
        else
        {
            t.Abort();
        }
    }
}
}
另一个表单只有一个名为lblName的标签:

但当我运行时,这种情况会发生:/:

如您所见,标签无法正常工作:/ 它们如下所示:

我建议使用计时器而不是线程。睡眠以避免阻塞UI线程,因为睡眠会阻止标签更新

while (ShowNo < Names.Count)
        {
            CustomMessageBox Msg = new CustomMessageBox();
            GlobalForm.Invoke((MethodInvoker)delegate()
            {
                try
                {
                    Msg.lblName.Text = Names[ShowNo];
                    Msg.Show();
                    System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
                    timer.Interval = 2000;
                    timer.Tick += (s, e) => Msg.Close();
                    timer.Start();
                }
                catch
                {
                    t.Abort();
                }
                ShowNo++;
            });
        }

顺便说一句,一旦线程完成运行,就不需要中止它。我也会使用while循环而不是递归方法调用。

ShowNoNames.Count也许吧?我把它改成了你说的,但仍然不起作用:/。我认为这里的问题有点复杂。我认为表单必须在UI线程上运行。非常简单。您正在睡觉,这会阻止标签刷新。改用定时器。你可以通过调用Msg.Refresh来作弊;在打电话睡觉之前。顺便说一下,这不是学习线程的最佳方法。线程用于操纵长时间运行的操作,如数据检索、分析等。任何GUI操作都必须在主线程上进行。您的GlobalForm不是很有用。您正在休眠UI线程,这会阻止调用。您是否尝试过使用BeginInvoke而不是Invoke?这不应该阻塞,它只是对调用进行排队。