我正在忙于一个调用servlet的Windows Phone应用程序,然后该servlet返回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的会话对象。然后,login方法将医生变量(sessionID和ok)设置为会话对象中现在的任何变量。 (唷!)
但是当我在按钮点击事件中调用我的医生对象上的getOk()和getSessionID()时,它会返回空白字符串,就像从未设置变量一样。我认为这是因为代码可能是异步运行的?
如何在getOk()和getSessionID()语句之前暂停onclick方法中的代码,直到调用 logonJsonDownloadComplete 方法。这意味着已收到这些值......如果这有意义吗?
另外值得一提的是,当我在logonJsonDownloadComplete方法中调用MessageDialog时,它可以工作,但是当我在click事件中调用它(当前已注释掉)时,它会返回空白变量。
答案 0 :(得分:2)
您不希望实际暂停UI线程中的代码。你想要的是正常的UI事件(重新绘制等),但是在登录完成之前要禁用一些/所有其他控件。
基本上在编写WP7应用程序时,有异步思考。你没有真正做Login
- 你正在做BeginLogin
。您需要在调用完成后将方法传递回执行,以及相关结果......然后您将进入下一个屏幕或其他任何屏幕。
请注意,异步目前相对比较麻烦,但使用C#5和.NET 4.5,它会通过async
/ await
功能变得更简单很多
答案 1 :(得分: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?*/
}
});
}