2

我正在研究一个“概念验证”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);
    }
}
4

1 回答 1

1

你有正弦看起来不错,但如果你仍然担心调用序列,我会建议你在你的 web 服务中创建一个新方法,它将按照你需要的任何顺序调用其他四个,并从你的 silverlight 调用这个新方法应用。

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

于 2010-09-03T17:21:50.057 回答