开发者

Silverlight Async Method Chaining (Possible gotchas?)

开发者 https://www.devze.com 2023-01-14 03:28 出处:网络
I am working on a \'proof of concept\' Silverlight 4 project and am learning the way of THE ASYNC.I have stopped fighting the urge to implement some pseudo-synchronous smoke and mirrors technique.I am

I am working on a 'proof of concept' Silverlight 4 project and am learning the way of THE ASYNC. I have stopped fighting the urge to implement some pseudo-synchronous smoke and mirrors technique. I am going to learn to stop worrying and love THE ASYNC.

Most of the time I just use a BusyIndicator while async methods are running and all is good but I have run into a few situations where I need to call methods sequentially. I put together this example and it works. But in my experience... if it works... there is something wrong with it.

When is this going to blow up in my face or steal my wife or date one of my daughters? Is there a better way to do this?

The Code:

开发者_Python百科public class CustomPage : Page
{
    static readonly object _AsyncMethodChain_Lock = new object();
    private Dictionary<Action<object>, string> _AsyncMethodChain = new Dictionary<Action<object>, string>();

    public Dictionary<Action<object>, string> AsyncMethodChain
    {
        get { lock (_AsyncMethodChain_Lock) { return this._AsyncMethodChain; } }
        set { lock (_AsyncMethodChain_Lock) { this._AsyncMethodChain = value; } }
    }

    private void CustomPage_Loaded(object sender, RoutedEventArgs e)
    {
        if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
        {
            var user = this.SecurityProvider.UserObject as TimeKeeper.UserServiceReference.User;

            if (user == null)
                return;

            this.AsyncMethodChain.Add(
                data =>
                {
                    var userServiceClient = new UserServiceClient();
                    userServiceClient.GetCompleted +=
                        (send, arg) =>
                        {
                            var userViewSource = this.Resources["userViewSource"] as CollectionViewSource;
                            userViewSource.Source = new List<UserServiceReference.User>(new UserServiceReference.User[1] { arg.Result });
                            userViewSource.View.MoveCurrentToPosition(0);
                            this.AsyncMethodChain.ExecuteNext(arg.Result.UserID, this.BusyIndicator);
                        };
                    userServiceClient.GetAsync(user.UserID);
                },
                "Loading user..."
                );

            this.AsyncMethodChain.Add(
                data =>
                {
                    var userID = (int)data;
                    var timeLogServiceClient = new TimeLogServiceClient();
                    timeLogServiceClient.FindByUserIDCompleted +=
                        (send, arg) =>
                        {
                            var timeLogViewSource = this.Resources["timeLogViewSource"] as CollectionViewSource;
                            timeLogViewSource.Source = arg.Result;
                            this.AsyncMethodChain.ExecuteNext(null, this.BusyIndicator);
                        };
                    timeLogServiceClient.FindByUserIDAsync(userID);
                },
                "Loading time logs..."
                );

            this.AsyncMethodChain.ExecuteNext(null, this.BusyIndicator);
        }
    }
}

public static class Extensions
{
    public static void ExecuteNext(this Dictionary<Action<object>, string> methods, object data, BusyIndicator busyIndicator)
    {
        if (methods.Count <= 0)
        {
            busyIndicator.BusyContent = "";
            busyIndicator.IsBusy = false;
            return;
        }
        else
        {
            var method = methods.Keys.ToList<Action<object>>()[0];
            busyIndicator.BusyContent = methods[method];
            busyIndicator.IsBusy = true;
        }

        methods.ExecuteNext(data);
    }

    public static void ExecuteNext(this Dictionary<Action<object>, string> methods, object data)
    {
        var method = methods.Keys.ToList<Action<object>>()[0];
        methods.Remove(method);
        method(data);
    }
}


What you have sine looks pretty good, but if you are still worried about the callsequence i would sugest that you create a new method in your webservice which will call the other four in whatever sequence you need them to and call this new method from your silverlight application.

I dont see the need for you to do that as your current implemenation is pretty good as well.

0

精彩评论

暂无评论...
验证码 换一张
取 消