简体   繁体   English

Xamarin Forms PCL消耗WCF并不总是返回值

[英]Xamarin Forms PCL Consuming WCF does not always return a value

I have a simple WCF service that is validating a login and return an object representing a user. 我有一个简单的WCF服务,它可以验证登录名并返回代表用户的对象。

It is being run with a Xamarin Forms PCL project. 它与Xamarin Forms PCL项目一起运行。 When I click the login button, the returned object returns null the first time, but when pressing a second time it returns the user object. 当我单击登录按钮时,返回的对象第一次返回null,但是当再次按下时返回用户对象。

The object is being created in the async functions on completed method. 在完成方法的异步函数中创建对象。

I am not quite sure what I am missing. 我不太确定自己缺少什么。

Here are pieces of code to help clarify. 以下是有助于澄清的代码段。

Thanks for any and all assistance! 感谢您的协助!

The function called by clicking the button... 通过单击按钮调用的功能...

private void buildLoginUser(string strUserName, string strPassword)
    {
        if (strUserName == null || strPassword == null) {
            strResult = "Please Enter User Name and Password.";
            DisplayAlert("Alert",strResult,"OK"); 
        } else {

            //IF USERNAME AND PASSWORD RECEIVED VALIDATE AGAINST DB
            //cl.ValidateUserAsync (strUserName, strPassword);
            //strResult = strUserRole;

            BuildClientService bcs = new BuildClientService ();
            //AuthenticateUser au = new AuthenticateUser ();

            TDMSClient cl = new TDMSClient ();
            cl = bcs.InitializeServiceClient();
            cl.ValidateUserAsync(strUserName, strPassword);
            //au.AuthenticateUserLogin (strUserName, strPassword, cl);
            //DisplayAlert("New User", lu.FullName, "OK");
            if (lu.FullName == null || lu.FullName == "") {
                DisplayAlert ("Alert", "NULL", "OK");
            } else {
                DisplayAlert ("Alert", lu.FullName, "OK");
            }

        }

The code that builds the user object... 构建用户对象的代码...

public class BuildClientService
{
    public static readonly EndpointAddress EndPoint = new EndpointAddress("http://wcf.thompsoncs.net/TDMS.svc");

    public string strUserRole = "";

    BasicHttpBinding binding = CreateBasicHttp();

    private static BasicHttpBinding CreateBasicHttp()
    {
        BasicHttpBinding binding = new BasicHttpBinding
        {
            Name = "basicHttpBinding",
            MaxBufferSize = 2147483647,
            MaxReceivedMessageSize = 2147483647
        };
        TimeSpan timeout = new TimeSpan(0, 0, 30);
        binding.SendTimeout = timeout;
        binding.OpenTimeout = timeout;
        binding.ReceiveTimeout = timeout;
        return binding;
    }

    public TDMSClient InitializeServiceClient(){
        TDMSClient cl = new TDMSClient();

        cl = new TDMSClient (binding, EndPoint);
        cl.ValidateUserCompleted += clOnValidateUserCompleted;

        return cl;
    }

    private void clOnValidateUserCompleted(object sender, ValidateUserCompletedEventArgs validateUserCompletedEventArgs)
    {
        TDMS.Login.lu = validateUserCompletedEventArgs.Result;

    }
}

Thanks! 谢谢! I changed the code and I am now getting a UI thread error... uikit consistency error you are calling a uikit method that can only be invoked from the ui thread. 我更改了代码,现在遇到UI线程错误... uikit一致性错误,您正在调用只能从ui线程调用的uikit方法。

private async void buildLoginUser(string strUserName, string strPassword)
    {
        if (strUserName == null || strPassword == null) {
            strResult = "Please Enter User Name and Password.";
            DisplayAlert("Alert",strResult,"OK"); 
        } else {

            //IF USERNAME AND PASSWORD RECEIVED VALIDATE AGAINST DB

            BuildClientService bcs = new BuildClientService ();

            TDMSClient cl = new TDMSClient ();
            cl = bcs.InitializeServiceClient();

            var task = Task.Factory.StartNew(() => cl.ValidateUserAsync(strUserName, strPassword));

            await task.ContinueWith (e => {
                if (lu.FullName == null || lu.FullName == "") {
                    DisplayAlert ("Alert", "NULL", "OK");
                } else {
                    DisplayAlert ("Alert", lu.FullName, "OK");
                }
            });

        }

    }

You need to make your method into an Async method. 您需要使您的方法成为Async方法。

At the moment your ValidateUserAsync method returns straight away meaning that lu.FullName is null or empty. 目前,您的ValidateUserAsync方法立即返回,表示lu.FullName为null或为空。

To turn your method into an async method add the word aync to the method and await to the async line you would like to await. 要将您的方法转换为异步方法,请在该方法上添加单词ayncawait您要await的异步行中等待。

private async void buildLoginUser(string strUserName, string strPassword)
{
    if (strUserName == null || strPassword == null) {
        strResult = "Please Enter User Name and Password.";
        DisplayAlert("Alert",strResult,"OK"); 
    } else {

        //IF USERNAME AND PASSWORD RECEIVED VALIDATE AGAINST DB
        //cl.ValidateUserAsync (strUserName, strPassword);
        //strResult = strUserRole;

        BuildClientService bcs = new BuildClientService ();
        //AuthenticateUser au = new AuthenticateUser ();

        TDMSClient cl = new TDMSClient ();
        cl = bcs.InitializeServiceClient();
        await cl.ValidateUserAsync(strUserName, strPassword);
        //au.AuthenticateUserLogin (strUserName, strPassword, cl);
        //DisplayAlert("New User", lu.FullName, "OK");
        if (string.IsNullOrEmpty(lu.FullName)) {
            DisplayAlert ("Alert", "NULL", "OK");
        } else {
            DisplayAlert ("Alert", lu.FullName, "OK");
        }

    }
}

Here's some more information and examples on Async/Await 这是有关Async / Await的更多信息和示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM