C#中的Delegate或Callback方法等待函数完成

时间:2014-07-22 21:08:41

标签: c# callback delegates windows-phone-8.1

所以这是背景,我将发布一些我正在尝试做的伪代码,因为实际的代码很长。因此,在我们的移动应用程序中,我们有一个身份验证服务器,可以在每个用户登录应用程序时为其生成会话ID。当他们使用App时,需要针对身份验证服务器验证sessionID,因此如果用户空闲时间过长,他们需要重新登录并获取新的sessionID。所以我需要做的是,在调用另一个Web服务方法之前,我需要检查用户是否有一个现有的sessionID,以及该sessionID是否仍然有效(这部分我已经能够做得很好)。到目前为止,一旦我在对服务的第一次异步调用之后进入会话验证方法,另一种方法正在继续,这导致问题,因为会话仍在被验证或正在生成新的sessionID。下面是我对VerifySession方法的看法(很多伪代码可以让我们了解实际代码很长的内容)

public MobileServiceSoapClient CheckSession()
        {
            AuthenticationService amProxy = new AuthenticationService();
            MobileServiceSoapClient serviceClient = new MobileServiceSoapClient();
            //first check if there's an existing session UUID and if that session is still valid
            AMUserSessionRequest sessionRequest = new AMUserSessionRequest();
            String sessionID = HelperMethods.GetStringForKey(Constants.keySessionID);
            if (sessionID.Length <= 0)
            {
                Debug.WriteLine("Generating new session ID");
                //no existing session available so send login request to AM Service and 
                AMUserLoginRequest loginRequest = new AMUserLoginRequest();                    
                amProxy.GetSessionCompleted += delegate(object sender, GetSessionCompletedEventArgs eventArgs)
                {
                    //get sessionID from response and generate work session for Mobile Service
                    Guid session = eventArgs.Result.session_ID;
                    Debug.WriteLine(eventArgs.Result.session_ID);

                    serviceClient.Get_SessionCompleted += delegate(object sender2, Get_SessionCompletedEventArgs eventArgs2)
                    {
                        Debug.WriteLine(eventArgs2.Result);
                        String validSession = String.Format("{0}", eventArgs2.Result);
                        //store session value in preferences
                        HelperMethods.StoreStringForKey(Constants.keySessionID, validSession);
                    };
                    serviceClient.Get_SessionAsync(session);
                };
                amProxy.GetSessionAsync(loginRequest);
            }
            else
            {
                Debug.WriteLine("validating existing sessionID");
                //there is a session so check if it's still valid
                sessionRequest.session_ID = Guid.Parse(sessionID);
                sessionRequest.signature = Helper_Classes.RsaSha1Signing.Sign(sessionID);
                amProxy.CheckSessionCompleted += delegate(object sender, CheckSessionCompletedEventArgs eventArgs)
                {
                    bool status = eventArgs.Result.ok;
                    if (!status)
                    {
                        //existing session isn't valid so generate new session
                        AMUserLoginRequest loginRequest = new AMUserLoginRequest();                            
                        amProxy.GetSessionCompleted += delegate(object getsessionSender, GetSessionCompletedEventArgs getsessionEvent)
                        {
                            //get sessionID from response and generate work session for Mobile Service
                            Guid session = getsessionEvent.Result.session_ID;
                            Debug.WriteLine(getsessionEvent.Result.session_ID);

                            serviceClient.Get_SessionCompleted += delegate(object sender2, Get_SessionCompletedEventArgs eventArgs2)
                            {
                                Debug.WriteLine(eventArgs2.Result);
                                String validSession = String.Format("{0}", eventArgs2.Result);
                                //store session value in preferences
                                HelperMethods.StoreStringForKey(Constants.keySessionID, validSession);
                            };
                            serviceClient.Get_SessionAsync(session);
                        };
                        amProxy.GetSessionAsync(loginRequest);
                    }
                    else
                    {
                        //sessionID is still a good value so use that to keep working
                        serviceClient.Get_SessionCompleted += delegate(object sender2, Get_SessionCompletedEventArgs eventArgs2)
                        {
                            Debug.WriteLine(eventArgs2.Result);
                            String validSession = String.Format("{0}", eventArgs2.Result);
                            //store session value in preferences
                            HelperMethods.StoreStringForKey(Constants.keySessionID, validSession);
                        };
                        serviceClient.Get_SessionAsync(Guid.Parse(sessionID));
                    }
                };
                amProxy.CheckSessionAsync(sessionRequest);
            }
            return serviceClient;
        }

所以现在当我想在Service方法中调用一个方法时,我需要做下面这样的事情,但我不知道如何这样做

public void GetClientList(String agentID)
        {
            Debug.WriteLine("checking session");
            MobileServiceSoapClient serviceClient = CheckSession();
            //I need some kind of callback here or something that will wait until the CheckSession method is completed before moving on to call the service I want
           serviceClient.GetClientsAsync(agentID) //this will get called pretty much right after the first if/else statement in CheckSession so in some cases it's returning incorrect results

1 个答案:

答案 0 :(得分:1)

据我所知,CheckSession方法是异步的。

所以你可以做两件事:

  1. 让它返回Task<MobileServiceSoapClient>await。您可以使用TaskCompletionSource<MobileServiceSoapClient>并将其结果设置在适当的事件/地点。
  2. 向方法添加Action<MobileServiceSoapClient>参数,并在方法完成其工作后调用它(这些是您在选项1中设置结果的相同位置)。
  3. 我选择了选项1.