Silverlight异步方法链接(可能的陷阱?)

时间:2010-09-03 15:59:29

标签: silverlight asynchronous method-chaining

我正在研究'概念验证'Silverlight 4项目,并且正在学习THE ASYNC的方式。我已经停止了实施一些伪同步烟雾和镜子技术的冲动。我将学会不再担心和爱ASYNC。

大部分时间我只是在异步方法运行时使用BusyIndi​​cator并且一切都很好但是我遇到了一些需要按顺序调用方法的情况。我把这个例子放在一起就可以了。但根据我的经验......如果它有效......它有问题。

这什么时候会在我脸上爆炸或偷走我的妻子或约会我的一个女儿? 有更好的方法吗?

守则:

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);
    }
}

1 个答案:

答案 0 :(得分:1)

你的正弦看起来很不错,但是如果你仍然担心callsequence我会认为你在你的webservice中创建一个新方法,它将以你需要的任何顺序调用其他四个并调用这个新方法来自你的silverlight应用程序。

我不认为您需要这样做,因为您当前的实施也非常好。