【问题标题】:Thread problem c#线程问题c#
【发布时间】:2011-09-30 20:54:51
【问题描述】:

我有 2 个线程。 在我的工作线程(不是主线程)中,我创建了一个图片框数组,有时我需要向主窗体添加一个新的图片框,但我无权访问此窗体。我在某处读到需要使用调用方法,但我只知道如何更新一个图片框或标签。 我不知道如何用这段代码做到这一点:

food[x].Location = new Point(100,100);
food[x].Size = new Size(10,10);
food[x].BorderStyle = BorderStyle.Fixed3D;
food[x].ImageLocation = "food.png";
this.Controls.Add(food[x]);
food[x].BringToFront;

谁能帮帮我?

【问题讨论】:

  • 你可能不应该有多个线程。
  • SLaks 是对的。这听起来像是一场等待发生的灾难。当两个线程试图访问相同的 UI 元素时,很难正确地进行 UI 编程。通常它的工作方式是只允许 UI 线程与 UI 元素对话。如果您有需要与 UI 对话的工作线程,那么您需要为工作线程设置某种方式与 UI 线程对话,然后 UI 线程将消息传递给 UI 对象。
  • 你是代码示例还是教程?
  • 将(创建)PictureBox 放入 UI 线程(可能是您正在谈论的“主”线程),然后从另一个线程调用 Dispatcher.BeginInvoke 以操作其中的所有对象主线程。

标签: c# multithreading forms main


【解决方案1】:

后台线程无法访问主线程拥有的 GUI 控件。

如果你想向 GUI 传递信息,线程必须与主线程进行通信,然后主线程操纵 GUI 控件。

BackgroundWorker 线程提供了向主线程发出信号的方法。例如,请参阅http://www.dotnetperls.com/backgroundworker

【讨论】:

    【解决方案2】:

    如果你使用 WPF,我建议使用 SynchronazationContext 来保存主线程,所有其他线程将使用 SynchronazationContext 的这个实例来访问主线程 (UI)。您以这种方式使用它(注意:我生成了一个执行此操作的方法,所有其他方法都将访问此方法以更新 UI):

    SynchronazationContext ctx = null;
    void DoSomething()
    {
        ctx = SynchronazationContext.Current;
        Thread t = new Thread(new ThreadStart(ThreadProc));
        t.Start();
    }
    
    //This method run in separate Threads
    void ThreadProc()
    {
        //Some algorithm here
    
        SendOrPostCallback callBack  = new SendOrPostCallback(UpdatePic);
        ctx.Post(callBack, String.Format("Put here the pic path");
    }
    void UpdatePic(string _text)
    {  
        //This method run under the main method
       //In this method you should update the pic
    }
    

    在 .NET 5.0 中,您可以通过将方法标记为 async 并在调用同步方法时写入 'await' 来调用这个复杂的函数 - 使同步方法成为异步方法并使用主线程更新 UI。

    【讨论】:

    • 所以我复制了这段代码,然后添加我的代码以在 updatepix 方法中添加一个图片框?而且我把路径(food.png)放在线程proc方法中?感谢所有的帮助。我明天早上 3 点试试看;)
    • 没错,这正是你应该做的,这样你就可以从其他线程访问主线程..顺便说一句,我现在注意到我的示例代码中的错误,我很快就会修复它,错误是我从 DoSomething 方法调用了 UpdatePic 方法,请尝试在没有错误的情况下立即运行它(我已删除它)。
    • 所以现在我遇到了问题。我收到一条错误消息。扩展方法不必在静态类中。抱歉,我只收到德语错误,希望您知道我的意思。所以这就是问题所在。另外你在 ctx.Post(callBack, String.Format("Put here the pic path");
    • 您的代码看起来不错,我认为异常是因为您的类是静态类,请尝试使用实例化类运行此代码(删除声明类上的静态)。如果您有更多问题,请继续回复。
    • 所以现在我有一个新错误:“方法”没有重载匹配委托“委托”在这一行:SendOrPostCallback callBack = new SendOrPostCallback(UpdatePic);
    【解决方案3】:

    在 WinForms 中,您应该只有一个 UI 线程,并且只有该线程才能创建或使用 UI 组件。

    如有必要,使用BackgroundWorker 加载图像,并在BackgroundWorker 完成时将PictureBox 创建留给UI 线程。

    【讨论】:

      猜你喜欢
      • 2022-01-08
      • 1970-01-01
      • 2011-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多