D
D
da_normalny_ya2021-02-25 20:23:09
WPF
da_normalny_ya, 2021-02-25 20:23:09

Why doesn't Dispatcher.Invoke work for all Controls?

I'm rewriting an application from WinForm to WPF and I've run into strange Invoke behavior.
There is a method that is called via

Task.Factory.StartNew(ThreadFunc, TaskCreationOptions.LongRunning);

The task of the code is to receive a message and, depending on the type, perform an action, so when a message about a disconnect is received, the properties of the controls on the form change quietly and everything works as usual, but when a byte array is received, after its conversion and an attempt to place it on the form, an exception occurs when resources are called from another thread, I tried it through a delegate and different forms of invocations, at the end I started to think that it was because of the reference type of the bitmap, but when cloning, the result is the same.

Actually the question is how to make it work normally and is it possible to implement image update using data binding?
MemoryStream ms = null;
while (true)
{
    if (_token.IsCancellationRequested) return;
                
    ms?.Dispose();
    _client.GetNextMessage(out var msg);
    if (msg.eventType == EventType.Data)
    {
        ms = new MemoryStream(msg.data);
        _bitmapImage = new BitmapImage();
        _bitmapImage.BeginInit();
        _bitmapImage.StreamSource = ms;
        _bitmapImage.EndInit();
        Dispatcher.Invoke(() =>
        {
            pictureBox.Source = _bitmapImage;
        });
    }
    else if (msg.eventType == EventType.Disconnected)
    {
        _cancelTokenSource.Cancel();

        Dispatcher.Invoke(() =>
        {
            Connect.IsEnabled = true;
            Disconnect.IsEnabled = false;
            pictureBox.Source = null;
        });
        MessageBox.Show("Трансляция закончилась или вы были отключены!", "Уведомление",
            MessageBoxButton.OK, MessageBoxImage.Asterisk);
        }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sumor, 2021-02-25
@Sumor

It is not clear from the code where the Dispatcher comes from.
It should point to a WPF thread dispatcher - in any WPF event handler, set this variable to CurrentDispatcher and the code above will work just fine.
Or take pictureBox.Dispatcher for that

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question