2

私は「概念実証」の Silverlight 4 プロジェクトに取り組んでおり、THE ASYNC の方法を学んでいます。私は、疑似同期の煙と鏡のテクニックを実装したいという衝動と闘うのをやめました。心配するのをやめて、THE 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

あなたが持っているものはかなり良さそうですが、それでもcallsequenceについて心配している場合は、Webサービスで新しいメソッドを作成して、必要な順序で他の4つを呼び出し、Silverlightからこの新しいメソッドを呼び出すことをお勧めします応用。

あなたの現在の実装もかなり良いので、あなたがそれをする必要があるとは思いません。

于 2010-09-03T17:21:50.057 に答える