Динамическое добавление элемента в xaml с многопоточным [duplicate]

Ваш код должен быть чем-то вроде этого

$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM Users WHERE UserName LIKE '$username'";
echo $query;
$result = mysql_query($query);

if($result === FALSE) {
    die(mysql_error("error message for the user")); 
}

while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}

. После этого вы получите запрос, напечатанный на экране. Попробуйте выполнить этот запрос на своем сервере и посмотрите, дает ли он желаемые результаты. В большинстве случаев ошибка содержится в запросе. Остальная часть кода верна.

242
задан Christos 1 December 2015 в 22:27
поделиться

12 ответов

Это обычная проблема с началом работы с людьми. Всякий раз, когда вы обновляете элементы пользовательского интерфейса из потока, отличного от основного потока, вам нужно использовать:

this.Dispatcher.Invoke(() =>
{
    ...// your code here.
});

Вы также можете использовать control.Dispatcher.CheckAccess() , чтобы проверить, является ли текущий поток владеет контролем. Если он действительно владеет, ваш код выглядит нормально. В противном случае используйте шаблон выше.

511
ответ дан oddRaven 1 September 2018 в 00:53
поделиться

это произошло со мной, потому что я попытался выполнить access UI компонент в another thread insted of UI thread

, как этот

private void button_Click(object sender, RoutedEventArgs e)
{
    new Thread(SyncProcces).Start();
}

private void SyncProcces()
{
    string val1 = null, val2 = null;
    //here is the problem 
    val1 = textBox1.Text;//access UI in another thread
    val2 = textBox2.Text;//access UI in another thread
    localStore = new LocalStore(val1);
    remoteStore = new RemoteStore(val2);
}

, чтобы решить эту проблему, обернуть любой вызов ui внутри , о чем упоминал Кандид в своем ответе

private void SyncProcces()
{
    string val1 = null, val2 = null;
    this.Dispatcher.Invoke((Action)(() =>
    {//this refer to form in WPF application 
        val1 = textBox.Text;
        val2 = textBox_Copy.Text;
    }));
    localStore = new LocalStore(val1);
    remoteStore = new RemoteStore(val2 );
}
17
ответ дан Community 1 September 2018 в 00:53
поделиться

Кроме того, другое решение гарантирует, что ваши элементы управления создаются в потоке пользовательского интерфейса, а не потоком рабочего потока, например.

0
ответ дан FindOutIslamNow 1 September 2018 в 00:53
поделиться

Если кто-то пытается работать с BitmapSource в WPF и потоках и имеет это же сообщение: сначала вызовите метод Freeze(), прежде чем передать параметр BitmapSource в качестве параметра потока.

27
ответ дан Hakam Fostok 1 September 2018 в 00:53
поделиться

Проблема в том, что вы вызываете GetGridData из фонового потока. Этот метод обращается к нескольким элементам управления WPF, которые привязаны к основному потоку. Любая попытка доступа к ним из фонового потока приведет к этой ошибке.

Чтобы вернуться к правильной теме, вы должны использовать SynchronizationContext.Current.Post. Однако в этом конкретном случае, похоже, большая часть работы, которую вы выполняете, основана на пользовательском интерфейсе. Следовательно, вы создадите фоновый поток, чтобы сразу вернуться к потоку пользовательского интерфейса и выполнить некоторую работу. Вам нужно немного реорганизовать свой код, чтобы он мог выполнять дорогостоящую работу в фоновом потоке, а затем публиковать новые данные в потоке пользовательского интерфейса после

2
ответ дан JaredPar 1 September 2018 в 00:53
поделиться

Как уже упоминалось здесь , Dispatcher.Invoke может заморозить UI. Вместо этого используйте Dispatcher.BeginInvoke.

Вот удобный класс расширений, который упрощает проверку и вызов диспетчера вызовов.

Пример использования: (вызов из окна WPF)

this Dispatcher.InvokeIfRequired(new Action(() =>
{
    logTextbox.AppendText(message);
    logTextbox.ScrollToEnd();
}));

Класс расширения:

using System;
using System.Windows.Threading;

namespace WpfUtility
{
    public static class DispatcherExtension
    {
        public static void InvokeIfRequired(this Dispatcher dispatcher, Action action)
        {
            if (dispatcher == null)
            {
                return;
            }
            if (!dispatcher.CheckAccess())
            {
                dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
                return;
            }
            action();
        }
    }
}
0
ответ дан Jeson Martajaya 1 September 2018 в 00:53
поделиться

Еще одно полезное использование для Dispatcher.Invoke - это немедленное обновление пользовательского интерфейса в функции, выполняющей другие задачи:

// Force WPF to render UI changes immediately with this magic line of code...
Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle);

Я использую это, чтобы обновить текст кнопки до « Обработка ... "и отключить его при выполнении запросов WebClient.

38
ответ дан Lauraducky 1 September 2018 в 00:53
поделиться

Я также обнаружил, что System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke() не всегда является диспетчером целевого контроля, точно так же, как dotNet пишет в своем ответе. У меня не было доступа к диспетчеру управления, поэтому я использовал Application.Current.Dispatcher, и он решил проблему.

2
ответ дан Paulus Limma 1 September 2018 в 00:53
поделиться

По какой-то причине ответ Кандиде не строился. Это было полезно, однако, поскольку это заставило меня найти это, которое отлично работало:

System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
    {
       //your code here...
    }));
11
ответ дан Sarah 1 September 2018 в 00:53
поделиться

Это работает для меня.

        new Thread(() =>
        {

        Thread.CurrentThread.IsBackground = false;
        Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate {

          //Your Code here.

        }, null);
        }).Start();
0
ответ дан sony vizio 1 September 2018 в 00:53
поделиться

Вам нужно обновить пользовательский интерфейс, поэтому используйте

Dispatcher.BeginInvoke(new Action(() => {GetGridData(null, 0)})); 
11
ответ дан Taryn 1 September 2018 в 00:53
поделиться

Я продолжал получать ошибку, когда добавлял каскадные comboboxes в свое приложение WPF и разрешал ошибку с помощью этого API:

    using System.Windows.Data;

    private readonly object _lock = new object();
    private CustomObservableCollection<string> _myUiBoundProperty;
    public CustomObservableCollection<string> MyUiBoundProperty
    {
        get { return _myUiBoundProperty; }
        set
        {
            if (value == _myUiBoundProperty) return;
            _myUiBoundProperty = value;
            NotifyPropertyChanged(nameof(MyUiBoundProperty));
        }
    }

    public MyViewModelCtor(INavigationService navigationService) 
    {
       // Other code...
       BindingOperations.EnableCollectionSynchronization(AvailableDefectSubCategories, _lock );

    }

Подробнее см. в https: // msdn .microsoft.com / запроса / dev14.query APPID = Dev14IDEF1 & амп;? л = EN-US & Amp; K = K (System.Windows.Data.BindingOperations.EnableCollectionSynchronization); к (TargetFrameworkMoniker-.NETFramework, версия% 3Dv4.7); к (DevLang-CSharp) & амп; й = истинно [/ д2]

0
ответ дан user8128167 1 September 2018 в 00:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: