【问题标题】:Dispatcher.Invoke not working in .NET 3.0 SP1Dispatcher.Invoke 在 .NET 3.0 SP1 中不起作用
【发布时间】:2010-05-24 11:53:50
【问题描述】:

我正在开发 WPF Windows 应用程序,但在 .NET 3.0 中运行该应用程序时遇到了问题。每次我尝试访问 System.Windows.Threading.Dispatcher.Invoke() 方法时,都会收到 method-not-found 错误。

基本上,我从主线程生成一个新线程,并尝试使用以下代码从新线程更改一些 UI 属性(基本上是更新进度条):

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 版本

任何帮助将不胜感激。

谢谢

卡皮尔

【问题讨论】:

    标签: c# .net-3.0


    【解决方案1】:

    WPF 类中存在相当多的变化。请注意此方法的 MSDN Library article 底部的“Supported in”注释。您需要在该计算机上至少安装 .NET 3.0 SP1,该服务包与 .NET 3.5 同时发布。

    没有很好的方法来检查这一点,[AssemblyVersion] 没有改变。依靠 Windows Update 自动升级 .NET 版本,这一点被掩盖了。如果您的客户阻止了这些更新,那么您必须设置一台安装了原始 .NET 3.0 版本的测试机器。

    解决方法很简单,一旦找到它们,请使用 3.0 RTM 中提供的重载。要求客户部署 3.5 SP1 是明智的。

    【讨论】:

    • 谢谢我发现我使用的 api 不应该在 .net 3.0 上工作
    【解决方案2】:

    试试这个:

    updateStatusDelegate usd = new updateStatusDelegate(progressBar.SetValue);
    Dispatcher.CurrentDispatcher.Invoke(
        usd, 
        DispatcherPriority.Background, 
        new object[] { ProgressBar.ValueProperty, Convert.ToDouble(perc) });
    

    Invoke 不是静态方法。您必须在类的实例上调用它。您可以使用静态属性Dispatcher.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 没有重载来转换它实际的类型。其次,用户的计算机被丢弃,需要好好清洁(擦拭、重新安装)。第三,您的问题在其他地方,您认为这是您遇到异常的地方,但实际上它在其他地方。

    【讨论】:

    • 请问,每个 DispatcherObject(一个窗口是一个 DispatcherObject)都有一个 Dispatcher 属性,它给出了 System.Windows.Threading.Dispatcher 的一个实例。它是我在代码中引用的 Dispatcher 属性。很抱歉没有在我的帖子中说清楚。但是,您的解决方案不会帮助我克服 methd not found 异常。我已经在 .net 3.0 sp2 env 中测试了该应用程序,它运行良好
    • @Kapil 会更新,但很难猜测,因为您没有提供有关未找到哪种方法的任何信息。我正在尝试复制(午饭时间)。
    • @Kapil perc 到底是什么类型?
    • @Kapil 也没有 3.0 SP2。
    • @Will perc 在我的代码中是一个整数。我还收到一个关于找不到 Dispatcher.Invoke 的方法的错误,其中包含我正在使用的 3 个参数。正如我在下面提到的,一旦我使用了 .net 3.0 友好的 api,我就能够克服它。
    【解决方案3】:

    发现我使用的方法在 .net 版本 3.0 中不受支持(仅在 .net 3.0sp2 及更高版本中支持)

    http://msdn.microsoft.com/en-us/library/cc647499%28VS.90%29.aspx

    所以,现在我正在使用另一个在 .net 3.0 中运行良好的 Invoke 重载方法,我能够解决这个问题。

    谢谢, 卡皮尔

    【讨论】:

      猜你喜欢
      • 2020-10-28
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-09
      相关资源
      最近更新 更多