gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 14:58:39 24 4
gpt4 key购买 nike

我的 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com