如何在for循环中每次更新标签

2023-12-08

我正在开发一个 WinForm 项目,其中有一个标签for环形。我想每次执行后显示标签label.text陈述。但它并不是每次都显示,而是在 for 循环完成后显示。

我试图通过使用来实现这一点Thread.Sleep()。但我不能。请帮我。 注意:- lblProgress 是一个标签

这是我的编码。

for (int i = 1; i <= sourceTable.Rows.Count - 1; i++)
{

    string checkout;
    checkout= sourceTable.Rows[i].Field<string>(0);

    dest = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["local"].ConnectionString);
    dest.Open();
    destcmd = new SqlCommand(checkout, dest);
    destcmd.ExecuteNonQuery();
    dest.Close();

    prcmail();
    prcmessagecheck();


    lblProgress.Text = "Hello World"+i;

    Thread.Sleep(10000);
}

每当您创建 WinForm 应用程序时,它都会启动一个新进程并创建一个新线程。对用户界面的任何更新都在与您的进程相同的线程上完成。这意味着当您的应用程序正在执行“繁忙工作”时,您的 UI 将被阻塞,因为它们位于同一线程上。这意味着,为了实现您想要实现的目标,您必须做一些额外的工作。

我们需要做的第一步是为您的工作例程创建一个函数(我们可以使用匿名函数,但由于您是 C# 新手,我认为如果我们将其分解出来会更容易理解),如下所示:

private void DoWork()
{
    for (int i = 1; i <= sourceTable.Rows.Count - 1; i++)
    {

        string checkout;
        checkout= sourceTable.Rows[i].Field<string>(0);

        dest = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["local"].ConnectionString);
        dest.Open();
        destcmd = new SqlCommand(checkout, dest);
        destcmd.ExecuteNonQuery();
        dest.Close();

        prcmail();
        prcmessagecheck();


        lblProgress.Text = "Hello World"+i;

        Thread.Sleep(1000); // I changed this from 10000 to 1000 (10 seconds down to 1 second)
    }
}

接下来,我们需要创建一个新线程来执行我们的DoWork()功能。目前还不清楚“触发”是什么来完成你的工作,但我假设它是一个按钮单击:

private void button1_click(object sender, EventArgs e)
{
    var work = new Thread(DoWork);
    work.Start();
}

所以现在,每当有人单击按钮时,我们都会启动一个新线程来执行我们的DoWork该线程中的函数。新线程产生,然后立即返回执行,并且我们的 GUI 现在将随着我们的线程在后台执行而实时更新。

可是等等!我们还有一个问题需要解决。问题是 Window 的表单控件不是线程安全的,如果我们尝试从 GUI 线程之外的另一个线程更新控件,我们将收到跨线程操作错误。解决这个问题的关键是使用InvokeRequired and Invoke.

首先,我们需要创建另一个仅执行标签更新的函数:

private void SetProgressLabel(int progress)
{
    lblProgress.Text = "Hello World" + progress;
}

在您的表单类中,我们还需要创建一个新的委托:

public partial class Form1 : Form
{
    private delegate void ProgressCallback(int progress);

    // ..
    // The rest of your code
    // ..
}

最后,改变你的DoWork()方法如下:

private void DoWork()
{
    for (int i = 1; i <= sourceTable.Rows.Count - 1; i++)
    {

        string checkout;
        checkout= sourceTable.Rows[i].Field<string>(0);

        dest = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["local"].ConnectionString);
        dest.Open();
        destcmd = new SqlCommand(checkout, dest);
        destcmd.ExecuteNonQuery();
        dest.Close();

        prcmail();
        prcmessagecheck();


        if (lblProgress.InvokeRequired)
        {
            lblProgress.Invoke(new ProgressCallback(SetProgressLabel), new object[] { i });
        }
        else
        {
            SetProgressLabel(i);
        }

        Thread.Sleep(1000); // I changed this from 10000 to 1000 (10 seconds down to 1 second)
    }
}

这使用标签的(源自Control) InvokeRequired属性来确定是否Invoke是必须的。它返回true or false。如果它是false,我们可以调用我们的SetProgressLabel()就像我们通常做的那样。如果它是true,我们必须使用Invoke来调用我们的函数。

恭喜!您刚刚制作了第一个线程安全应用程序。

现在,顺便说一句,您没有正确释放和处置您的物品。我建议你改变你的DoWork()代码如下:

private void DoWork()
{
    for (int i = 1; i <= sourceTable.Rows.Count - 1; i++)
    {
        string checkout;
        checkout = sourceTable.Rows[i].Field<string>(0);

        using (dest = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["local"].ConnectionString))
        {
            dest.Open();
            using (destcmd = new SqlCommand(checkout, dest))
            {
                destcmd.ExecuteNonQuery();
                dest.Close();

                prcmail();
                prcmessagecheck();

                if (lblProgress.InvokeRequired)
                {
                    lblProgress.Invoke(new ProgressCallback(SetProgressLabel), new object[] { i });
                }
                else
                {
                    SetProgressLabel(i);
                }

                Thread.Sleep(1000); // I changed this from 10000 to 1000 (10 seconds down to 1 second)
            }
        }
    }
}

因为我包裹了你IDisposable's into using块,一旦超出范围,资源将自动被处置。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在for循环中每次更新标签 的相关文章

随机推荐

  • TIME_WAIT 连接过多,出现“无法分配请求的地址”

    我有一个小型 Web 应用程序 它打开 TCP 套接字连接 发出命令 读取响应 然后关闭对特定 REST 端点的每个请求的连接 我已经开始使用 Apache JMeter 对端点进行负载测试 并注意到运行一段时间后 我开始看到诸如 无法分配
  • Laravel 4 - 无法检索一对多关系中的数据

    我有一个报价模型 class Quote extends Eloquent public function quote lines return this gt hasMany QuoteLine 还有一个 QuoteLine 模型 cla
  • 添加 Azure Ad Oauth2 JWT 令牌声明

    我只是想知道是否有办法通过 Azure 门户向 Azure Ad OAuth2 JWT 令牌添加或指定自定义声明 或者这是唯一可能的代码方面 据我所知 Azure AD目前不支持发出自定义声明 作为解决方法 我们可以使用 Azure AD
  • 通过名称获取 React 组件

    有没有办法通过名称访问 React 组件 例如 使用 React devtools 我可以搜索组件并使用以下命令访问控制台中最近选择的组件 r 有没有办法在没有 React 开发工具的情况下访问这些组件 IE 我可以使用查询来获取这些组件吗
  • 删除R中欧元符号后面的字符

    我有一个欧元符号保存在 欧元 变量中 euro lt u20AC euro 1 并且 eurosearch 变量包含 此 SOW 中定义的服务 价格为 15 896 80 欧元 如果从 执行 eurosearch 1 services as
  • 如何使用 iso_c_binding 声明指针的指针?

    我正在写一个iso c 绑定在 Fortran 中调用具有以下原型的 C 函数 int zmat run const size t inputsize unsigned char inputstr size t outputsize uns
  • 电源外壳。修改 ascii 文本文件字符串,其中行号字符串已打开。交换机和 .NET 框架或 cmdlet 和管道?哪个更快?

    如何使用易于阅读且易于使用 PowerShell 5 添加 修改 删除的搜索字符串来修改 Windows ascii 文本文件中的字符串 LINE2 行号 LINE2 is on 此脚本将解析 2500 行文件 找到 139 个字符串实例
  • 如何过滤 JSON 对象

    我有一个 JSON 对象 它是包含姓名 FName 城市 班级 联系人的学生列表 现在我只想过滤属于特定城市的对象 学生 我可以过滤邮件json对象吗 Students id 1 Name Student1 FName FName1 Cla
  • 我无法从 Hadoop 客户端连接到 Hadoop 服务器

    Hadoop 服务器位于 Kubernetes 中 Hadoop客户端位于外部网络 所以我尝试使用 kubernetes service 来使用 Hadoop 服务器 但hadoop fs put不适用于 Hadoop 客户端 据我所知 n
  • R ggplot2 - geom_smooth,具有来自第三个连续变量的渐变颜色

    有没有办法绘制平滑曲线 x var1 y var2 并相对于第三个连续变量 z var3 为其着色 我正在使用以下代码 library ggplot2 x runif 100 20 20 y 2 x x 2 rnorm 100 0 50 z
  • 多文件上传器仅发送一个文件

    我有一个多文件输入 我可以选择多个文件 但是当我在表单操作页面上 var dump 文件变量时 只有一个文件
  • 子查询返回超过 1 个值

    我需要在 SQL Server 2008 中设置一个作业 以便在每个月的第一天运行 向我们的客户发送电子邮件 但是 我不知道如何循环子查询的结果 导致出现此错误消息 子查询返回超过 1 个值 这是不允许的 当 子查询后面有 gt 或者当子查
  • Hibernate 批量大小混乱

    该程序一个接一个地执行数万次连续插入 我以前从未使用过 Hibernate 我的性能变得非常慢 如果我只是手动连接并执行 SQL 我的速度会快 10 12 倍 根据许多 hibernate 教程 我的 batch size 设置为 50 这
  • 上传到Heroku DB rake:迁移问题

    heroku 上传出现问题 对于 RoR 来说还很陌生 所以请原谅初学者的问题 我正在关注 Ruby on Rails 教程 http ruby railstutorial org 在搭建脚手架之后 我输入 heroku rake db m
  • JavaFX 的 TextField 的值更改侦听器

    我想添加一种listener to my JavaFX s TextField当用户改变值时TextField 应用程序在控制台上打印一些内容 我进行了搜索 发现以下非常相似的问题 JTextField 的值更改侦听器 提到的问题的答案非常
  • 带有 $.ajax 类型的自定义标头 jnop 或 json

    我在使用 jQuery ajax JSON 或 JSONP 请求发送一些自定义标头时遇到问题 代码如下所示 ajax beforeSend function xhr xhr setRequestHeader X VER VER xhr se
  • 迭代并打印常规闭包的内容

    在一个循环中 我创建了 4 个闭包并将它们添加到列表中 closureList for int i 0 i lt 4 i def cl def A i closureList add cl closureList each print it
  • 查找数组中的特殊数字

    数组中有很多数字 除了一个特殊数字出现一次外 每个数字都出现3次 那么问题来了 如何找到数组中的特殊数字呢 现在我只能提出一些基数排序和快速排序的方法 无法利用问题的性质 所以我需要一些其他的算法 感谢您的帮助 将数字按位 mod 3 添加
  • 如何向 VBA ListBox 添加水平滚动条

    我想向 VBA ListBox 添加水平滚动条 看来内置的ListBox不会自动添加水平滚动条 我有许多字段 其内容超出了列表框的宽度 因此用户无法读取 I found 本文 但是由于访问 ListBox 的 hwnd 这在 VBA 中显然
  • 如何在for循环中每次更新标签

    我正在开发一个 WinForm 项目 其中有一个标签for环形 我想每次执行后显示标签label text陈述 但它并不是每次都显示 而是在 for 循环完成后显示 我试图通过使用来实现这一点Thread Sleep 但我不能 请帮我 注意