C#在新线程中单击按钮更新图像

标签 c# .net wpf

我的 XAML 中有一个 Image 标签列表,我希望一个接一个地更新它们,然后休眠。

我有以下代码,但它们都立即更新并且 UI 保持卡住状态直到完成。

请你帮我让它在设置图像源时“实时”更新吗?

这是我目前所拥有的:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace JobMonitor
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // Add the test lights to a list
        private readonly Dictionary<int, Image> imageDictionary;

        public MainWindow()
        {
            InitializeComponent();

            imageDictionary = new Dictionary<int, Image>
            {
                {1, TestLight1},
                {2, TestLight2},
                {3, TestLight3},
                {4, TestLight4},
                {5, TestLight5},
                {6, TestLight6},
            };
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Dispatcher.InvokeAsync(ChangeImage);

        }

        private void ChangeImage()
        {
            // Loop through each of the tests
            foreach (var testLight in imageDictionary)
            {
                ChangeImageLights(testLight.Value);

                Thread.Sleep(1000);
            }
        }

        private void ChangeImageLights(Image img)
        {

            var myImage3 = new Image();
            var redLightImage = new BitmapImage();
            redLightImage.BeginInit();
            redLightImage.UriSource = new Uri("red_light.png", UriKind.Relative);
            redLightImage.EndInit();
            myImage3.Stretch = Stretch.Fill;
            myImage3.Source = redLightImage;

            img.Source = redLightImage;
        }
    }
}

XAML:

<Image Margin="0,0,20,0" Height="40" Source="green_light.png" Stretch="Fill" Name="TestLight1" />
<Image Margin="0,0,20,0" Height="40" Source="green_light.png" Stretch="Fill" Name="TestLight2" />
<Image Margin="0,0,20,0" Height="40" Source="green_light.png" Stretch="Fill" Name="TestLight3" />
<Image Margin="0,0,20,0" Height="40" Source="green_light.png" Stretch="Fill" Name="TestLight4" />
<Image Margin="0,0,20,0" Height="40" Source="green_light.png" Stretch="Fill" Name="TestLight5" />
<Image Margin="0,0,20,0" Height="40" Source="green_light.png" Stretch="Fill" Name="TestLight6" />

我认为使用 Dispatcher.InvokeAsync() 可以解决我的问题,这就是为什么我把它放在那里....

最佳答案

您可以推断 InvokeAsync 实际上并未在另一个线程上运行,因为您可以在 ChangeImageLights 中执行操作。一种方法是利用 BackgroundWorker:

// new private class variable
private BackgroundWorker _worker = new BackgroundWorker();

// constructor code
public .ctor()
{
    _worker.WorkerReportsProgress = true;
    _worker.DoWork += (s, e) =>
    {
        // Loop through each of the tests
        foreach (var testLight in imageDictionary)
        {
            _worker.ReportProgress(1, testLight.Value);

            Thread.Sleep(1000);
        }
    }
    _worker.ProgressChanged += (s, e) =>
    {
        var myImage3 = new Image();
        var redLightImage = new BitmapImage();
        redLightImage.BeginInit();
        redLightImage.UriSource = new Uri("red_light.png", UriKind.Relative);
        redLightImage.EndInit();
        myImage3.Stretch = Stretch.Fill;
        myImage3.Source = redLightImage;

        ((Image)e.UserState).Source = redLightImage;
    }
}

BackgroundWorker 启动一个新线程并在该线程上运行 DoWork 处理程序。然后,当您调用 ReportProgress 时,它会处理切换线程,以便您可以实际修改 ProgressChanged 处理程序中的 UI。

现在后台线程在报告更多进度之前实际上会休眠 1 秒。

关于C#在新线程中单击按钮更新图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18272780/

相关文章:

.net - 是否可以对 Azure DevOps (VSTS) 部署配置进行版本控制?

c# - 检查DateTime是否在特定范围内

c# - X509Certificate.CreateFromCertFile - 指定的网络密码不正确

c# - 返回具有与 userId LINQ 匹配的最新时间戳的实体

.net - WPF动画StackPanel的宽度从0到自动?

C# WPF - 等待页面加载

c# - 排队函数不执行出队

c# - 传递整个对象或该对象的属性的方法哪个性能更高?

wpf - RoutedCommands 已执行和预览执行事件

wpf - 在wpf运行时添加控件