委托或回调方法在c#中等待一个函数完成

本文关键字:一个 函数 等待 回调 方法 | 更新日期: 2023-09-27 18:14:20

这是背景,我将发布一些伪代码,因为实际代码很长。因此,在我们的移动应用程序中,我们有一个认证服务器,当他们登录到应用程序时,为每个用户生成一个sessionID。当他们使用应用程序时,sessionID需要对认证服务器进行验证,因此,如果用户闲置太长时间,他们需要重新登录并获得一个新的sessionID。所以我需要做的是,在另一个web服务方法被调用之前,我需要检查用户是否有一个现有的sessionID,如果那个sessionID仍然有效(这部分我已经能够做得很好)。到目前为止,一旦我在对服务的第一次异步调用之后进入会话验证方法,其他方法就会继续前进,这会导致问题,因为会话仍在验证中,或者正在生成新的sessionID。下面是我为verifsession方法所做的(因为实际代码很长,所以有很多伪代码来了解发生了什么)

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

委托或回调方法在c#中等待一个函数完成

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

你可以做两件事:

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

我选选项1