0

我正忙于开发一个调用 servlet 的 Windows Phone 应用程序,然后依次返回 JSON,然后将其转换为 C# 对象。

当用户单击按钮时,将执行此代码:

    //Login button pressed
    private void btnLogin_Click(object sender, RoutedEventArgs e)
    {

        //Get needed variables
        Doctor doctor = new Doctor();
        string userName = txtUsername.Text;
        string password = txtPassword.Text;

        if ((userName != "" || userName != null) && (password != "" || password != null))
        {
            //Log doctor in
            doctor.Login(userName, password);
        }
        else
        {
            MessageBox.Show("Please make sure all fields are filled out");
        }

        //If doctor has valid session ID, forward to search page
        if ((doctor.getOk() != "false") || (doctor.getOk() != "") && (doctor.getSessionID() != ""))
            NavigationService.Navigate(new Uri("/Search.xaml", UriKind.Relative));
            //MessageBox.Show("Ok: "+doctor.getOk()+"\nSessionID: "+doctor.getSessionID());
        else
            MessageBox.Show("Login failed, please check your username and password and try again");
    }

这是医生课:

public class Doctor
{
    string sessionID = "";
    string username = "";
    string password = "";
    string ok = "";

    public void Login(string argUsername, string argPassword){           

        if ((username != "" || username != null) && (password != "" || password != null))
        {
            //Set doctor username and password for later reference if necesarry
            this.username = argUsername;
            this.password = argPassword;

            //Url to login servlet
            string servletUrl = "http://196.3.151.36:8080/AuthService/login?u=" + username + "&p=" + password;

            //Calls Servlet
            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(logonJsonDownloadComplete);
            client.DownloadStringAsync(new Uri(servletUrl, UriKind.Absolute));

        }

    }

    //Converts returned Json to C# Object
    private void logonJsonDownloadComplete(object sender, DownloadStringCompletedEventArgs e)
    {
        var jsonResponse = e.Result;
        var session = JsonConvert.DeserializeObject<Session>(e.Result);
        ok = session.ok;
        sessionID = session.sid;
        MessageBox.Show("Ok: " + ok + "\nSessionID: " + sessionID);
    }

    public string getOk()
    {
        return this.ok;
    }

    public string getSessionID()
    {
        return this.sessionID;
    }


}

这是会话类:

public class Session
{
    public string sid { get; set; }
    public Account account { get; set; }
    public string ok { get; set; }
    public string expiry { get; set; }
}

现在的问题是:当用户单击登录按钮时,会创建一个新的医生对象,然后在该医生对象上调用 login() 方法,然后再调用 servlet。当 json 成功下载后,logonJsonDownloadComplete方法在医生类中被调用。然后基本上获取 json,并将其转换为几乎只有一堆 getter 和 setter 的会话对象。然后登录方法将医生变量(sessionID 和 ok)设置为会话对象中的任何内容。(呸!)

但是,当我在按钮单击事件中对我的医生对象调用 getOk() 和 getSessionID() 时,它会返回空白字符串,就像从未设置过变量一样。我认为这是因为代码可能异步运行?

如何在 getOk() 和 getSessionID() 语句之前在 onclick 方法中暂停我的代码,直到调用logonJsonDownloadComplete方法。这意味着已经收到了这些值......如果这有意义吗?

编辑

还可能值得一提的是,当我在 logonJsonDownloadComplete 方法中调用 MessageDialog 时,它可以工作,但是当我在 click 事件中调用它(当前已注释掉)时,它会返回空白变量。

4

2 回答 2

2

您不想真正暂停 UI 线程中的代码。您想要的是发生正常的 UI 事件(重新绘制等),但在登录完成之前禁用某些/所有其他控件。

基本上在编写 WP7 应用程序时,您必须异步思考。你不是真的在做Login——你在做BeginLogin。您需要在调用完成时向该方法发送回调以执行相关结果......然后您继续进入下一个屏幕或其他任何内容。

请注意,异步目前相对繁琐,但在 C# 5 和 .NET 4.5 中,通过/功能将变得更加简单。asyncawait

于 2012-06-21T10:22:06.217 回答
0

我认为您正在寻找行动代表:http: //msdn.microsoft.com/en-us/library/018hxwa8.aspx

在这里,我举了一个例子:

    public void IsStringEmpty(string input, Action<bool, Exception> callback)
    {
        try
        {
            if (string.IsNullOrEmpty(input)) callback(true, null);
            else callback(false, null);
        }
        catch (Exception ex)
        {
            callback(false, ex);
        }
    }

    public void Test()
    {
        string test = string.Empty;

        // show busy indicator here

        IsStringEmpty(test, (result, error) =>
        {

            //hide busy indicator here

            if (error == null)
            {
                if (result) { /* string is empty */}
                else { /* string is not empty */}
            }
            else
            {
                /* show/log error?*/
            }
        });
    } 
于 2012-06-21T10:25:13.800 回答