Android, Xamarin Forms PCL, PortableRest PCL и вызов Async Web Api

Я пытаюсь использовать PortableRest для выполнения асинхронного вызова службы Web API 2.2 Rest из Xamarin Forms.

Я думаю, что у меня какая-то проблема с контекстом взаимоблокировки / синхронизации, но я не могу ее решить (новичок в async и т. Д.).

Кто-нибудь может помочь?

Мой метод тестирования контроллера (удален любой вызов базы данных) -

public IEnumerable<ContentModel> GetTestRest()
{
    return new List<ContentModel> {
        new ContentModel() {Categoryid = 1, Title = "Title"}};
}

Мои прохождения модульного теста -

[TestMethod]
public async Task TestRest()
{
    MyNewsApiClient MyNewsApiClient = new MyNewsApiClient();

    var models = await MyNewsApiClient.TestRest();
    int count = models.Count;
    Assert.AreEqual(1, count);
}

Мой метод прокси PortableRest (PCL) -

public async Task<List<ContentModel>> TestRest()
{
    var request = new RestRequest();
    request.Resource = "Content/GetTestRest";

    return await ExecuteAsync<List<ContentModel>>(request);
}

Xamarin Forms ContentPage (PCL) -

public partial class NewsType1CP : ContentPage
{
    public NewsType1CP ()
    {
        InitializeComponent ();
    }

    protected override void OnAppearing ()
    {
        LoadData ();  // this is a sync call of an async method, not sure how else to  approach, make OnAppearing async?
    }

    public async Task LoadData ()
    {
        Debug.WriteLine ("LoadData");

        HeaderLabel.Text = "Load Data!";

        MyNewsApiClient api = new MyNewsApiClient ();

        var cm = await api.TestRest ();
        // this will work on its own, control returns to this method - await api.GetDelay ();

        HeaderLabel.Text = "After! - ";

        NewsListView.ItemsSource = cm;
    }
}

Ожидание api.TestRest () никогда не приводит к установке HeaderLabel.After или ListView.

Если я просто добавлю тестовый прокси-метод GetDelay (), который не вызывает PortableRest через return await ExecuteAsync> (request);

public async Task<bool> GetDelay ()
{
    await Task.Delay (1000);
    return true;
}

Потом все "работает".

Спасибо за вашу помощь, при необходимости я скачаю исходный код PortableRest (в настоящее время используется Nuget dll), просто не был уверен, не хватает ли чего-то базового на этом верхнем уровне.


person WickedW    schedule 17.07.2014    source источник
comment
Вы проверили фактический сетевой трафик? возможно, при подключении произошла ошибка. Вы также можете попробовать использовать HttpClient.GetAsync ‹› для устранения проблем с подключением   -  person Sten Petrov    schedule 17.07.2014
comment
Спасибо @StenPetrov, я проверил трафик, и вы правы, нет вызова, сделанного извне, теперь я окружил вызов в блоке try и смотрю дальше   -  person WickedW    schedule 18.07.2014


Ответы (1)


Верно, в конечном итоге это не имеет ничего общего с Async (или какой-либо проблемой с PortableRest), но подумал, что поделюсь, если это может помочь другим.

В конце концов я поставил блок try (теперь очевиден следующий шаг!) И поймал это исключение -

Метод не найден: 'System.Net.Http.HttpClientHandler.set_AutomaticDecompression'.

Итак, глядя на это -

http://davidburela.wordpress.com/2013/07/12/error-when-using-http-portable-class-library-compression/

PortableRest уже был в моем PCL Forms, но мне нужно было добавить Nuget клиентских библиотек Microsoft Http в мое приложение для Android.

Затем я получил -

Ошибка: ConnectFailure (запрошенный адрес недействителен в данном контексте)

Я подумал, что это может быть связано с разрешениями Android, но в данном случае этого не было (хотя теперь я понимаю, что мне все равно нужно добавить разрешение для Интернета для будущих звонков).

Поскольку я запускаю свое приложение на виртуальной машине (из GenyMotion / Virtual Box), приложение Android не может получить доступ к LocalHost (где находится мой веб-API)

Итак, из этого -

http://bbowden.tumblr.com/post/58650831283/accessing-a-localhost-server-from-the-genymotion

Я могу подтвердить, что использование адреса, указанного в VirtualBox> File> Preferences> Network> VirtualBox Host-Only Network Adapter> Modify, прекрасно справляется со своей задачей.

Спасибо за вашу помощь.

person WickedW    schedule 18.07.2014