Dispatcher.Invoke не работает в .NET 3.0 SP1
Вопрос
Я разрабатываю приложение Windows WPF, и у меня возникают проблемы с запуском приложения в .NET 3.0.Каждый раз, когда я пытаюсь получить доступ к методу System.Windows.Threading.Dispatcher.Invoke(), я получаю сообщение об ошибке «метод не найден».
По сути, я создаю новый поток из основного потока и пытаюсь изменить некоторые свойства пользовательского интерфейса (в основном обновляю индикатор выполнения) из нового потока, используя следующий код:
updateStatusDelegate usd = new updateStatusDelegate(progressBar.SetValue);
Dispatcher.Invoke(usd, System.Windows.Threading.DispatcherPriority.Background, new object[] { System.Windows.Controls.ProgressBar.ValueProperty, Convert.ToDouble(perc) });
Может ли кто-нибудь помочь мне понять, почему я сталкиваюсь с этой ошибкой в версии .NET 3.0?Я могу реализовать это в .NET 3.0 SP2.Но я думаю, что .NET не распространяется независимо и поставляется только с версией .NET 3.5.Моя цель — избавиться от зависимости .net 3.5 и иметь зависимость от версии .NET 3.0.
Любая помощь будет оценена по достоинству.
Спасибо
Капил
Решение
В классах WPF произошли значительные изменения.Обратите внимание на аннотацию «Поддерживается в» внизу страницы. Статья библиотеки MSDN для этого метода.На этом компьютере должен быть установлен как минимум .NET 3.0 SP1 — пакет обновления, выпущенный одновременно с .NET 3.5.
Нет хорошего способа проверить это, [AssemblyVersion] не изменилась.Это удалось скрыть, полагаясь на то, что Центр обновления Windows автоматически обновляет версию .NET.Если ваш клиент заблокирует эти обновления, вам придется настроить тестовую машину, на которой установлена исходная версия .NET 3.0.
Обходной путь достаточно прост: как только вы их найдете, используйте перегрузку, доступную в RTM 3.0.Было бы разумно попросить клиента развернуть версию 3.5 SP1.
Другие советы
Попробуй это:
updateStatusDelegate usd = new updateStatusDelegate(progressBar.SetValue);
Dispatcher.CurrentDispatcher.Invoke(
usd,
DispatcherPriority.Background,
new object[] { ProgressBar.ValueProperty, Convert.ToDouble(perc) });
Invoke не является статическим методом.Вы должны вызвать его в экземпляре класса.Вы можете использовать статическое свойство Диспетчер.CurrentDispatcher чтобы получить (или создать) диспетчер, связанный с текущим потоком.
(Кстати, вы ошибаетесь, утверждая, что это будет работать с другой версией фреймворка.)
Я взял следующую программу (все в MainWindow.xaml.cs):
public partial class MainWindow : Window
{
private string perc = ".25";
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
updateStatusDelegate usd = new updateStatusDelegate(
progressBar.SetValue);
Dispatcher.Invoke(usd,
System.Windows.Threading.DispatcherPriority.Background,
new object[] {
System.Windows.Controls.ProgressBar.ValueProperty,
Convert.ToDouble(perc) });
var dbl = Convert.ToDouble(perc);
perc = (dbl + .1).ToString();
}
}
public delegate void updateStatusDelegate(DependencyProperty dp, object value);
и запустил его для версий 3.0, 3.5 (sp1) и 4.0.Это работает на каждой версии.
Это приводит меня к трем выводам.Во-первых, perc может не быть строкой, а Convert.ToDouble не имеет перегрузки для преобразования того типа, которым он на самом деле является.Во-вторых, компьютер пользователя захламлен и нуждается в хорошей чистке (стирании, переустановке).В-третьих, ваша проблема в другом, и вы думать здесь вы получаете исключение, но на самом деле оно где-то в другом месте.
Выяснилось, что метод, который я использовал, не поддерживается в .net версии 3.0 (поддерживается только в .net 3.0sp2 и более поздних версиях).
http://msdn.microsoft.com/en-us/library/cc647499%28VS.90%29.aspx
Итак, теперь, когда я использую другой перегруженный метод Invoke, который отлично работает в .net 3.0, я могу решить эту проблему.
Спасибо, Капил