2016-12-23 9 views
0

Быстрый фон. Использовал Flurl внутри библиотеки классов, которую я создал, чтобы упростить мой код для связи с облачным хранилищем api. Прекрасно работает при вызове библиотеки из консольного приложения, используемого для тестирования всех методов. Когда вы пытаетесь использовать ту же библиотеку классов с простой winform, тот же метод, который очень быстро возвращается с помощью консольного приложения, кажется, никогда не возвращает результат. При отладке код ниже попадает в строку «.GetAsync()», а затем никогда не возвращает результат, а также предотвращает продолжение сеанса отладки. Сообщение об ошибке никогда не выдается.Вызов Flurl из приложения winforms никогда не возвращает результат

Я нашел комментарий на сайте Flurl, что у кого-то, похоже, была такая же проблема, но, похоже, они не поставили вопрос здесь, как было рекомендовано. Было бы весьма полезно оценить все, что могло бы указать мне в правильном направлении.

Flurl код завернутый в методе асинхронного

public async Task<AccountInfo> Authorize() 
    { 
     string credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes(Utils.ToNonSecureString(accountId) + ":" + Utils.ToNonSecureString(applicationKey))); 
     var result = await B2UrlType.Authorize 
      .WithHeader("Authorization", "Basic " + credentials) 
      .GetAsync() 
      .ReceiveJson<AccountInfo>(); 
     return result; 
    } 

Console приложение вызов код, который отлично работает

if (client == null) 
     { 
      var vault = new Vault(); 
      Console.WriteLine("Retrieving account keys"); 
      client = new Client(vault.GetAccountId(), vault.GetApiKey()); 
      Console.WriteLine("Successfully retrieved account keys"); 
      Console.WriteLine("Created new client"); 
      client.Authorize().GetAwaiter().GetResult(); 
     } 

Winform код вызов, который не возвращает

private Client client; 
    public MainWindow() 
    { 
     InitializeComponent(); 
     var vault = new Vault(); 
     client = new Client(vault.GetAccountId(), vault.GetApiKey()); 
     client.Authorize().GetAwaiter().GetResult(); 

    } 
+0

Для тех, кто ищет решение этой проблемы, я нашел то, что сработало для меня [здесь] (http: // stackoverflow.com/вопросы/32501683/c-sharp-flurl-and-httpclient-no-response-from-rest-api) –

ответ

0

Ваш оригинальный код зависает, потому что вы блокируете поток пользовательского интерфейса, обратившись к GetResult(). Это не специфическая для Flurl проблема; это async 101.

Ваше исправление не работает, потому что вы больше не блокирует, но вы также не await ИНГ свой призыв к Auth(), который на самом деле эквивалентом просто звоню client.Authorize() без await или GetResult() непосредственно из вашего MainWindow() конструктора. Вы больше не блокируете, но вы стремитесь и забываете, то есть любые исключения, которые могут возникнуть в client.Authorize, останутся незаметными, вызывая ошибки, которые трудно отследить.

Правило большого пальца: Как и в любой асинхронной библиотеке, вызовите методы асинхронного анализа Flurl из других методов async и ожидайте их, когда это возможно. В консольных приложениях у вас есть, чтобы заблокировать основной поток где-то, или приложение просто выйдет до завершения задач. (Мне нравится делать это на самом верху - определите метод MainAsync, содержащий всю работу и вызов MainAsync().Wait() от Main.) Но с приложениями WinForms есть хорошее место для размещения асинхронного кода, где вам никогда не придется блокировать или запускать, Забыть: Обработчики событий.

Я не делал WinForms в течение длительного времени, но на основе других ответов он кажется приличным событием для кода инициализации: Window.Load. Перемещение вашего разрешения на авторизацию было бы хорошим решением. Что-то вроде этого:

private async void MainWindow_Load(object sender, System.EventArgs e) 
{ 
    await client.Authorize(); 
} 
+0

Да. Ушел от него и вернулся со свежими глазами, чтобы увидеть мою ошибку (и). Я вернулся и обнаружил несколько строк кода, которые блокировались в библиотеке, которую я построил. Тестирование уже около 4 часов без каких-либо проблем. Реализация flurl значительно упростила устранение неполадок и радикальное сокращение строк кода. Цените свой ответ и потрясающую библиотеку. –

0

Это то, что работает, но я до сих пор не знаю, почему ...

private Client client; 
    public MainWindow() 
    { 
     InitializeComponent(); 
     var vault = new Vault(); 
     client = new Client(vault.GetAccountId(), vault.GetApiKey()); 
     Auth(); 

    } 

    private async void Auth() 
    { 
     await client.Authorize(); 
    } 

Обертывание вызов авторизации в методе асинхронном позволило HttpPost заполнить и вернуть результаты.