Ошибка при обновлении Source в Image
Написал вот такой код для того чтоб отобразить в WPF окне картинку, переданную клиентом:
namespace ScreenStream
{
public partial class MainWindow : Window
{
private TcpListener _listener;
public MainWindow()
{
InitializeComponent();
StartServer();
}
private async void StartServer()
{
_listener = new TcpListener(IPAddress.Any, 12345);
_listener.Start();
while (true)
{
var client = await _listener.AcceptTcpClientAsync();
_ = Task.Run(() => HandleClient(client));
}
}
private async Task HandleClient(TcpClient client)
{
using (var networkStream = client.GetStream())
using (var memoryStream = new MemoryStream())
{
await networkStream.CopyToAsync(memoryStream);
memoryStream.Position = 0;
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memoryStream;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
Dispatcher.Invoke(() =>
{
ScreenshotImage.Source = bitmapImage;
});
}
client.Close();
}
protected override void OnClosed(EventArgs e)
{
_listener?.Stop();
base.OnClosed(e);
}
}
}
проблема в том, что ScreenshotImage.Source = bitmapImage;
выдает ошибку System.InvalidOperationException: 'The calling thread cannot access this object because a different thread owns it.'
.
Пробовал чисто в качестве бреда по разному обьявлять Dispatcher
, например:
this.Dispatcher.Invoke(() =>
{
ScreenshotImage.Source = bitmapImage;
});
или
Application.Current.Dispatcher.Invoke(() =>
{
ScreenshotImage.Source = bitmapImage;
});
но результат всяко тот же, что впринципе не удивительно, а других идей как решить пробелму у меня нет погуглил, везде пишут что ошибка фикситься простым добавлением Dispatcher.Invoke
, а мне это почему то не помогло
Ответы (1 шт):
Проблема связана с тем, что BitmapImage
должен быть инициализирован на основном потоке, прежде чем его можно будет использовать в Dispatcher.Invoke
.
Попробуйте создать и инициализировать BitmapImage
внутри Dispatcher.Invoke
таким образом:
Dispatcher.Invoke(() =>
{
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memoryStream;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
ScreenshotImage.Source = bitmapImage;
});