使用 Thread 和 Dispatcher.Invoke 多次绘制图像的 WPF 问题
WPF Problem with drawing Image multiple times using Thread and Dispatcher.Invoke
我多次尝试在 Image 控件上绘制内容,我需要在每次绘制后刷新和查看它,同时用户控件保持可访问、负责和非冻结状态。
绘图本身非常快。
我将 Thread 与 Dispatcher.Invoke 一起使用,但它似乎不起作用。 MainWindow 变得无响应,直到绘图周期结束。
您可能会看到我尝试了 2 个变体,在 Invoke 内部和外部都有循环。
有人可以就这个问题给我建议吗?
编辑:视图是在位图上绘制图像的对象,returns它作为图像控制的来源。
iView 是 MainWindow 上的图像控件。
private void Draw()
{
// setting size of image
view.DataHeight = 500;
view.DataWidth = TDRConnection.MAX_DATAPOINTS;
view.Height = (int)gView.ActualHeight;
view.Width = (int)gView.ActualWidth;
//drawing
iView.Source = view.DrawPixels(connection.GetMeasurementData(),
TDRConnection.MAX_SUPPORTED_CHANNELS,
portColors);
}
private void LiveDrawingAS()
{
Dispatcher.Invoke(() => {
int safety = 0;
for (; safety < 300 && doLiveDrawing; safety++) {
Draw();
//Thread.Sleep(100);
}
MessageBox.Show($"Done {safety} drawings");
});
}
private void LiveDrawingNAS()
{
int safety = 0;
for (; safety < 300 && doLiveDrawing; safety++) {
Dispatcher.Invoke(() => {
Draw();
//Thread.Sleep(100);
});
}
MessageBox.Show($"Done {safety} drawings");
}
private void bLive_Click(object sender, RoutedEventArgs e)
{
doLiveDrawing = true;
new Thread(new ThreadStart(LiveDrawingAS)).Start();
}
private void bStop_Click(object sender, RoutedEventArgs e)
{
doLiveDrawing = false;
}
EDIT2:我已经在 Invoke 之外创建位图,现在 MainWindow 可以响应,但是 Image 控件是空的,所以它仍然没有用:
private void LiveDrawingNAS()
{
WriteableBitmap wbm;
int safety = 0;
for (; safety < 30 && doLiveDrawing; safety++) {
wbm = DrawBitmap();
Dispatcher.Invoke(() => {
iView.Source = wbm;
});
}
MessageBox.Show($"Done {safety} drawings");
}
好的,所以我找到了解决方案。位图需要冻结:
private void LiveDrawingOutUI()
{
WriteableBitmap wbm;
int safety = 0;
for (; safety < 300 && doLiveDrawing; safety++) {
wbm = DrawBitmap();
wbm.Freeze();
Dispatcher.Invoke(() => {
iView.Source = wbm;
});
}
MessageBox.Show($"Done {safety} drawings");
}
干杯!
好的,所以我找到了解决方案。它需要冻结位图。现在我的图片更新了新数据,而 Window 有响应:
private void LiveDrawingOutUI()
{
WriteableBitmap wbm;
int safety = 0;
for (; safety < 300 && doLiveDrawing; safety++) {
wbm = DrawBitmap();
wbm.Freeze();
Dispatcher.Invoke(() => {
iView.Source = wbm;
});
}
MessageBox.Show($"Done {safety} drawings");
}
干杯!
我多次尝试在 Image 控件上绘制内容,我需要在每次绘制后刷新和查看它,同时用户控件保持可访问、负责和非冻结状态。 绘图本身非常快。
我将 Thread 与 Dispatcher.Invoke 一起使用,但它似乎不起作用。 MainWindow 变得无响应,直到绘图周期结束。
您可能会看到我尝试了 2 个变体,在 Invoke 内部和外部都有循环。 有人可以就这个问题给我建议吗?
编辑:视图是在位图上绘制图像的对象,returns它作为图像控制的来源。
iView 是 MainWindow 上的图像控件。
private void Draw()
{
// setting size of image
view.DataHeight = 500;
view.DataWidth = TDRConnection.MAX_DATAPOINTS;
view.Height = (int)gView.ActualHeight;
view.Width = (int)gView.ActualWidth;
//drawing
iView.Source = view.DrawPixels(connection.GetMeasurementData(),
TDRConnection.MAX_SUPPORTED_CHANNELS,
portColors);
}
private void LiveDrawingAS()
{
Dispatcher.Invoke(() => {
int safety = 0;
for (; safety < 300 && doLiveDrawing; safety++) {
Draw();
//Thread.Sleep(100);
}
MessageBox.Show($"Done {safety} drawings");
});
}
private void LiveDrawingNAS()
{
int safety = 0;
for (; safety < 300 && doLiveDrawing; safety++) {
Dispatcher.Invoke(() => {
Draw();
//Thread.Sleep(100);
});
}
MessageBox.Show($"Done {safety} drawings");
}
private void bLive_Click(object sender, RoutedEventArgs e)
{
doLiveDrawing = true;
new Thread(new ThreadStart(LiveDrawingAS)).Start();
}
private void bStop_Click(object sender, RoutedEventArgs e)
{
doLiveDrawing = false;
}
EDIT2:我已经在 Invoke 之外创建位图,现在 MainWindow 可以响应,但是 Image 控件是空的,所以它仍然没有用:
private void LiveDrawingNAS()
{
WriteableBitmap wbm;
int safety = 0;
for (; safety < 30 && doLiveDrawing; safety++) {
wbm = DrawBitmap();
Dispatcher.Invoke(() => {
iView.Source = wbm;
});
}
MessageBox.Show($"Done {safety} drawings");
}
好的,所以我找到了解决方案。位图需要冻结:
private void LiveDrawingOutUI()
{
WriteableBitmap wbm;
int safety = 0;
for (; safety < 300 && doLiveDrawing; safety++) {
wbm = DrawBitmap();
wbm.Freeze();
Dispatcher.Invoke(() => {
iView.Source = wbm;
});
}
MessageBox.Show($"Done {safety} drawings");
}
干杯!
好的,所以我找到了解决方案。它需要冻结位图。现在我的图片更新了新数据,而 Window 有响应:
private void LiveDrawingOutUI()
{
WriteableBitmap wbm;
int safety = 0;
for (; safety < 300 && doLiveDrawing; safety++) {
wbm = DrawBitmap();
wbm.Freeze();
Dispatcher.Invoke(() => {
iView.Source = wbm;
});
}
MessageBox.Show($"Done {safety} drawings");
}
干杯!