0

私は、サーブレットを呼び出してJSONを返し、それがC#オブジェクトに変換されるWindowsPhoneアプリケーションの作業で忙しいです。

このコードは、ユーザーがボタンをクリックしたときに実行されます。

    //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()メソッドが呼び出され、次にサーブレットが呼び出されます。jsonが正常にダウンロードされると、logonJsonDownloadCompleteメソッドがdoctorクラスで呼び出されます。次に、基本的にjsonを取得し、それをセッションオブジェクトに変換します。このオブジェクトには、ゲッターとセッターがたくさんあります。次に、loginメソッドは、doctors変数(sessionIDおよびok)を現在セッションオブジェクトにあるものに設定します。(ふぅ!)

しかし、ボタンクリックイベントでドクターオブジェクトに対してgetOk()とgetSessionID()を呼び出すと、変数が設定されていないように空白の文字列が返されます。これは、コードがおそらく非同期で実行されるためだと思いますか?

getOk()およびgetSessionID()ステートメントの前にonclickメソッドでコードを一時停止して、logonJsonDownloadCompleteメソッドが呼び出されるようにするにはどうすればよいですか。これは、値が受信されたことを意味します...それが理にかなっている場合は?

編集

また、logonJsonDownloadCompleteメソッドでMessageDialogを呼び出すと機能しますが、クリックイベント(現在コメントアウトされている)で呼び出すと、空白の変数が返されることにも言及する価値があります。

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 に答える