C#:线程不工作



我希望在转换器处理时显示 GIF 图像。但是 GIF 图像从不显示显示,转换器过程成功完成,大约需要 20 秒,因此图片框是空白的。如果我用MessageBox.Show替换转换器过程,Gif图像和Message.Show都可以正常工作。

我需要做什么?

Thread th = new Thread((ThreadStart)delegate                  
{
    pictureBox1.Image = Image.FromFile("loading_gangnam.gif");                                 
    Thread.Sleep(5000);
});
th.Start(); 
//MessageBox.Show("This is main program");
Converted = converter.Convert(input.FullName, output);

UI 的绘制是在 paint 事件期间完成的,仅当您的代码完成它所考虑的任何操作时,才会进行处理。

此外,您当前的代码已损坏。切勿从工作线程操作 UI 控件(如 PictureBox)。这会导致"检测到跨线程操作"(或类似)异常。

选项:

  • 处理图像的一部分,然后让它绘制,并安排计时器或其他事件以暂时继续绘制
  • 隔离(非 UI)图像的背景线程上执行工作,定期创建当前工作图像的副本,并使用pictureBox1.Invoke(...)副本设置为图片框的内容。

还有一种显式方法可以让事件在 UI 循环中处理,但这确实是一种糟糕的做法,我什至无法通过名称提及它。

你已经把线程倒过来了。您希望 UI 线程立即显示 GIF,但转换在新线程上运行。应如下所示:

Thread th = new Thread((ThreadStart)delegate                  
{
    Converted = converter.Convert(input.FullName, output);
});
th.Start(); 
// should probably check pictureBox1.InvokeRequired for thread safety
pictureBox1.Image = Image.FromFile("loading_gangnam.gif");   

一些进一步的阅读:http://msdn.microsoft.com/en-us/library/3s8xdz5c.aspxhttp://msdn.microsoft.com/en-us/library/ms171728.aspx

您正在从与主 UI 线程不同的线程访问窗体控件。你需要使用 Invoke()。

有关示例,请参见此处

尝试使用此函数来设置loading_gangnam.gif图像:

public void newPicture(String pictureLocation)
{
    if (InvokeRequired)
    {
        this.Invoke(new Action<String>(newPicture), new object[] { pictureLocation });
    }
    pictureBox1.Image = Image.FromFile(pictureLocation);
    pictureBox1.Refresh();
}

正在处理的项目有几个线程都访问相同的表单,这对我有用!

最新更新