0

In my searching the common solution to this problem is to add an event handler to handle once the invoke operation has completed.

Unfortunately, my IValueConverter needs to return a value so having the handler is not much help. I have also tried a do/while loop until the operation is complete but the loop never closes.

I have also tried just a simple wait operation but it still returns null. I know that my DomainService returns the correct value but the Converter never gets to see it.

Is there anything I can do in this instance? Having a converter that works would remove/reduce pretty much all future problems I can forsee.

My code: (i need something like this that works)

    InspectDomainContext context = new InspectDomainContext();
    string name;
    InvokeOperation<string> inv;

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string id = (string)value;
        inv = context.GetName(id);
        inv.Completed += new EventHandler(inv_Completed);
        // return here after the handler has completed
        return name;
    }

    void inv_Completed(object sender, EventArgs e)
    {
        name = inv.Value;
    }
xhedgepigx
  • 340
  • 1
  • 2
  • 19

2 Answers2

1

(new answer as it's completely different to the first one!)

This presumes you're using some sort of ViewModel datacontext pattern...

Rather than do this in an IValueConverter, you can create a second property on your ViewModel to hold the converted value.

public class MyViewModel
{
    private string _id;
    public string Id
    {
        get { return _id; }
        set 
        { 
            _id = value; 
            UpdateConvertedName(_id);
        }
    }

    private void UpdateConvertedName(string id)
    {
        // Same as your 'Convert' code above
    }

    private void inv_Completed(object sender, EventArgs e)
    {
        Name = inv.Value;        
    } 

    public string Name { get; set; }
}

So instead of binding to ID with a converter, you'd just bind directly to Name. Whenever ID is changed, Name will be updated asynchronously. You may also need some INotifyPropertyChanged in the Name getter/setter, if you're using ViewModels you'll already be familiar with all of that.

As you're stuck with asynchronous calls, it could also be worth adding some UI indicators that a value is old or incomplete - I don't know what your setup is, but theoretically the client machine could be on a 28.8k connection from the other side of the world or a very slow mobile device, so your response time would be very poor. But that's not really relevant to the answer at hand!

pete the pagan-gerbil
  • 3,136
  • 2
  • 28
  • 49
0

Could you just call it synchronously instead?

return context.GetName(id.ToString());

Otherwise, you will probably have to wait for .NET 4.5 and the async/await keywords, as I understand it (not played with it yet myself) this will let you put a 'wait' point somewhere in your method to not continue until the async part has finished.

But there's no way to make an asynchronous call behave like a synchronous one, as you're asking for. Why does it need to be asynchronous?

pete the pagan-gerbil
  • 3,136
  • 2
  • 28
  • 49