Как правильно вызвать задачу на главной странице - PullRequest
0 голосов
/ 28 сентября 2018

Если await можно использовать только асинхронными методами, как я могу вызвать задачу из MainPage ()?

Мой пример кода:

public MainPage()
{
    InitializeComponent();
    label.Text=await Task.Run(TaskTest); //this doesn't work
}

private async Task<string> TaskTest()
    {
        try
        {
            using (WebClient client = new WebClient())
            {
               return await client.DownloadStringTaskAsync("https://www.example.com/return.php");
//also tried w/ no success:
//return client.DownloadStringTaskAsync("https://www.example.com/return.php").Result;
            }
        }
        catch (Exception)
        {
            throw;
        }
    }

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

Избегайте async void методов огня и забывания.

Однако обработчики событий являются единственным исключением из этого правила.

Ссылка Асинхронное / ожидание - лучшие практики асинхронного программирования

В этом случае, так какВы хотите дождаться задачи, а затем создать и событие и обработчик, которые облегчили бы желаемое поведение

public MainPage() {
    InitializeComponent();
    Downloading += OnDownloading; //subscribe to event
    Downloading(this, EventArgs.Empty); //raise event to be handled
}

private event EventHandler Downloading = delegate { };

private async void OnDownloading(object sender, EventArgs args) {
     //Downloading -= OnDownloading; //unsubscribe (optional)
    label.Text = await TaskTest(); //this works
}

private async Task<string> TaskTest() {
    try {
        using (WebClient client = new WebClient()) {
           return await client.DownloadStringTaskAsync("https://www.example.com/return.php");
        }
    } catch (Exception) {
        throw;
    }
}
0 голосов
/ 28 сентября 2018

Вы не можете сделать метод Main() асинхронным, и, таким образом, вы можете использовать ключевое слово await в теле функции Main().

Простой обходной путь, который вы можете реализовать, отредактировав текущий код, заставляет вашу функцию TaskTest() возвращать void, поэтому вам не нужно ждать ее вызова.

Пример:

public MainPage()
{
    InitializeComponent();
    TaskTest();
}
private async void TaskTest()
{
    try
    {
        using (WebClient client = new WebClient())
        {
           label.Text = await client.DownloadStringTaskAsync("https://www.example.com/return.php");
        }
    }
    catch (Exception)
    {
        throw;
    }
}

Редактировать

Если вам придется ждать возвращаемого значения асинхронного вызова без использования await, вы можете продолжить.и используйте некоторое время, чтобы проверить, завершен ли Task или нет.

Task<string> accessTokenTask = Task.Run<string>(() => MethodToGetToken());
// wait until operation is done.
while(!accessTokenTask.IsCompleted)
{
    accessTokenTask.Wait():
}
// once the task completes, the runtime will step out of the while loop
// and you can access your Token in the Result

string token = accessTokenTask.Result;

Надеюсь, что это отвечает на ваш вопрос.

...