Xamarin& RestSharp - 异步调用挂起/永不返回

时间:2014-09-29 19:06:23

标签: android android-asynctask xamarin restsharp c#-5.0

我正在Xamarin中编写一个Android应用程序,使用restsharp执行异步json调用。我的设置涉及一个android java绑定库(jar文件转换为c#)。这个库有一个类,它是Application的子类,看起来像这样

HealthData.java(它是jar的一部分并作为项目引用到应用程序中)意图是在加载任何活动之前运行它。

import android.app.Application;

public class HealthData extends Application {
    private int intTest;

    HealthData () {
        intTest = 0;
    }

    public int getIntTest(){
        return intTest;
    }

    public void setIntTest(int value){
        intTest = value;
    }
}

我在AndroidManifest.xml中加载此子类,如下所示 -

<application android:label=“demo" android:name=“.HealthData">
        <activity android:name=“.MainActivity" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
    </application>

我执行异步调用的主动(用c#编写)看起来像这样 -

using RestSharp;

namespace demo
{
    [Activity (Label = "demo", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        static string TAG = "PRINT-ME";

        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);

            // Set our view from the "main" layout resource
            SetContentView (Resource.Layout.Main);

            callme();

            Log.Info (TAG, "callme returns");
        }

        private async void callme()
        {
            // Call the method that runs asynchronously.
            string result = await WaitAsynchronouslyAsync();

            // Display the result.
            TextView txt = FindViewById<TextView> (Resource.Id.textViewAsync);
            txt.Text = result;
        }

        public async Task<string> WaitAsynchronouslyAsync()
        {
            // fetch some json via restsharp
            var client = new RestClient ("http://rxnav.nlm.nih.gov/REST/RxTerms/rxcui/");
            var request = new RestRequest (String.Format ("{0}/allinfo", "198440"));

            Log.Info (TAG, "before awaiting");

            // ExecuteTaskSync
            IRestResponse resp = await ExecuteTaskAsync (client, request);

            return resp.Content;
        }
}

问题 - 当我在清单文件中使用HealthData时,ExecuteTaskAsync blocks / never永远不会返回。如果我在AndroidManifest.xml中跳过加载HealthData,则异步调用返回并且一切正常。

当我使用HealthData时,知道为什么异步调用失败了吗?我没有看到logcat的任何错误或警告。

我尝试使用c#版本的HealthData并在Manifest.xml中使用它,异步调用工作正常。

1 个答案:

答案 0 :(得分:2)

因为callme返回void而不是返回一个Task,所以在callme中发生的任何异常都会被吃掉并且永远不会冒出来,所以这可能就是你永远不会看到它完成的原因。

试试这个:

// Mark OnCreate as 'async'
protected async override void OnCreate (Bundle bundle)
{
    base.OnCreate (bundle);

    // Set our view from the "main" layout resource
    SetContentView (Resource.Layout.Main);

    var callMeTask = callme();
    await callMeTask;

    if (callMeTask.IsFaulted) {
        Log.Info(TAG, "callMe Failed with exception: " + callMeTask.Exception);
    } else {
        Log.Info (TAG, "callme returns");
    }
}

// Have callMe return Task
private async Task callme()
{
    // No changes
}