tags:

views:

217

answers:

3

I am developing a WPF windows application and am getting into a trouble running the app in .NET 3.0. Everytime that I try to access the System.Windows.Threading.Dispatcher.Invoke() method, I get a method-not-found error.

Basically, I spawn a new thread from the main thread and try to change some UI properties (basically update a progress-bar) from the new thread using the following code:

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

Can someone help me understand why do I encounter this error in .NET 3.0 version? I am able to get this going in .NET 3.0 SP2. But I guess .NET is not distributed independantly and is packaged only with .NET 3.5 version. My goal is to get away with the dependancy of .net 3.5 and have a dependancy on .NET 3.0 version

Any help would be appreciated.

Thanks

Kapil

+1  A: 

Try this:

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

Invoke is not a static method. You must call it on an instance of the class. You can use the static property Dispatcher.CurrentDispatcher to get (or create) the dispatcher associated with the current thread.

(BTW, you are incorrect that this would work with a different version of the framework.)


I have taken the following program (all in 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);

and have run it targeting 3.0, 3.5 (sp1) and 4.0. It works on each version.

This leads me to three conclusions. First, perc may not be a string and Convert.ToDouble does not have an overload to convert the type it actually is. Second, the user's computer is trashed and needs a good cleaning (wipe, reinstall). Third, your issue is elsewhere and you think this is where you're getting the exception, but in fact it is somewhere else.

Will
Will, every DispatcherObject (a window is a DispatcherObject) has a Dispatcher property which gives an instance of the System.Windows.Threading.Dispatcher) . Its this Dispatcher property that I am refering to in my code.Sorry for not making it clear in my post. However, your solution will not help me get past the methd not found exception.And I have tested the app in .net 3.0 sp2 env and it works very well
Kapil
@Kapil will update but its hard to guess as you don't provide any info on what method is not found. Am trying to repro (late lunch).
Will
@Kapil exactly what type is `perc`?
Will
@Kapil also there is no 3.0 SP2.
Will
@Will perc was an integer in my code. I was also getting an error about method not found for the Dispatcher.Invoke with the 3 args that I was using. As I mentioned below, once i used a .net 3.0 friendly api, I was able to get past that.
Kapil
@Will Also 3.0 sp2, as I said earlier, is not available as a standalone download, but was packaged with .net 3.5sp1.
Kapil
@Will How did you test your code in the .net 3.0? Did you uninstall all the .net versions and installed only .net 3.0?
Kapil
@Kapil Finally found a mention of sp2 on MS. Information about breaking changes are VERY slight. I tested by changing my targeting. Congrats on finding that link!
Will
@Will you bet! MS guys really need a course on documentation!
Kapil
+2  A: 

There's been a fair amount of flux in the WPF classes. Note the "Supported in" annotation at the bottom of the MSDN Library article for this method. You'll need to have at least .NET 3.0 SP1 installed on that machine, the service pack that was released at the same time as .NET 3.5.

There is no good way to check for this, the [AssemblyVersion] didn't change. This was papered-over by relying on Windows Update automatically upgrading the .NET version. If your customer blocks these updates then you'll have to setup a test machine that has the original .NET 3.0 release installed.

The workaround is simple enough, once you find them, use an overload that is available in 3.0 RTM. Asking the customer to deploy 3.5 SP1 would be wise.

Hans Passant
Thanks I figured out that the api I was using was not supposed to work on .net 3.0
Kapil
+1  A: 

Figured out that the method I was using was not supported in .net version 3.0 (only supported in .net 3.0sp2 onwards)

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

So, now that I am using another overloaded method of Invoke which works fine in .net 3.0, I am able to resolve this issue.

Thanks, Kapil

Kapil