Pergunta

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;
    }
Foi útil?

Solução

(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!

Outras dicas

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?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top