【问题标题】:how to make a method which can change text property of any text box from any thread in C#?如何制作一个可以从 C# 中的任何线程更改任何文本框的文本属性的方法?
【发布时间】:2023-03-30 10:43:01
【问题描述】:

我不是一个真正优秀的 C# 程序员。我习惯了 C 但不习惯 C#。

我知道从 UI 线程以外的线程我们无法更改文本框和标签的属性。

所以在尝试了几种不同的方法后,我一直在使用这种方法:

 item.Invoke(new EventHandler(delegate
            {
                item.Text = text;
            }));

然后在写了一些代码之后,我发现每次都这样做很无聊而且效率低下,所以我做了一个方法:

static void change_text_from_different_thread(TextBox item, string text)
        {
            item.Invoke(new EventHandler(delegate
            {
                item.Text = text;
            }));

        }

然后我尝试在我的线程中使用它,问题是我无法从线程发送 TextBox。

假设这是我的主题:

{

change_text_from_different_thread(textbox1,"Hi");

}

然后我得到这个错误:

非静态字段、方法或 属性

那么你能告诉我如何传递文本框吗? 顺便说一句,我的调用方法有可能是错误的或非常危险的,但我找不到更简单的方法。如果真的很糟糕,请告诉我。如果没问题,也请告诉我。如果通过使用其他方法,事情变得更好更容易,也请告诉我。

这是我第一次提问,如果我错过了一些东西,请见谅。 非常感谢。

这是我的方法:

static void gyro_self_check_thread_function()
{
//lab lab
}

这就是我创建线程并启动它的方式:

private void Gyro_self_check_button_Click(object sender, EventArgs e)
        {

            Gyro_self_check_status_label.Text = "Status: Checking....";
            gyro_self_testing_groupBox.Update();
            _serialPort.Write(Protocal_Values.gyro_self_checking_request, 0, 2);


            Thread gyro_self_check_thread = new Thread(gyro_self_check_thread_function);
            gyro_self_check_thread.Start();

            //Thread gyro_self_check_thread = new Thread(gyro_self_check_thread);
            //gyro_self_check_thread.Start();



        }

【问题讨论】:

  • 从工作线程更新 UI 通常是一种非常值得怀疑的做法。请参阅 BackgroundWorker.RunWorkerCompleted、TaskScheduler.FromCurrentSynchronizationContext 和 C# 5 async/await 关键字以了解替代方案。确保你不做一些你不应该做的容易做的事情。应该会痛的。
  • 补充汉斯所说的,这里的想法是将您的用户界面逻辑与您的业务逻辑分开。从这个问题的声音来看,您正试图将两者紧密结合在一起。不要。
  • 如果结果来自另一个线程,您将如何更改文本框文本?
  • 我读到了这个dotnetperls.com/progressbar,我有了一个想法。但是如果我对我的所有代码都这样做,我有很多小线程,它会更长。我读到了这个 TaskScheduler.FromCurrentSynchronizationContext 但我什么都不懂。我有时间限制,所以现在,我将只使用调用。但我想知道是否有办法将一些任务传递给 UI 线程,以便在下次处理时处理它们。当我读到这个“TaskScheduler.FromCurrentSynchronizationContext”时,我想到了这个想法。
  • 任何人都可以提供一个包含TaskScheduler.FromCurrentSynchronizationContext 的教程的建议吗?

标签: c# multithreading invoke


【解决方案1】:

看起来您的线程方法也是静态的,而 textbox1 是非静态字段,因此无法从静态方法访问它。

如果是这种情况,那么您可以使您的线程方法成为非静态的并且它应该可以编译。

【讨论】:

  • 不知道如何制作非静态线程方法。让我搜索一下,看看我能不能学。
  • 我找不到合适的阅读地点,你能给我一个好的参考吗。
  • 更新您的问题以包括线程创建代码和线程方法,可能从方法修饰符中删除静态就足够了。
  • 已更新。我试图在我的 WindowsFormsApplication1 中创建一个公共类。然后我在课堂上做了一个方法。在课堂上我无法访问 UI 组件。
  • gyro_self_check_thread_function 可能不应该是静态的
【解决方案2】:

正如另一位发表评论的那样,这可能是静态访问与非静态访问的问题。为了缓解这个问题,你也许可以把它写成 TextBox 的扩展方法:

static class ExtensionMethods
{
     static void change_text_from_different_thread(this TextBox item, string text)
     {
         item.Invoke(new EventHandler(delegate
             {
                 item.Text = text;
             }));

     }
}

那你这样称呼它:

textbox1.change_text_from_different_thread("Hi");

【讨论】:

  • 如果他的问题确实与他从静态方法调用此代码并且textbox1 不是静态的事实有关,那么此更改将无济于事。
  • 是的。我想我是想解决这个问题,如果他把它设为非静态的,那么将它作为多种形式的成员函数。
  • 我刚试过。服务是正确的,我无法从其他线程发送文本框。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多