Возврат списка строк с использованием await и async - PullRequest
0 голосов
/ 10 мая 2018
  • У меня есть веб-сайт ASP.NET (4.5), развернутый в среде Azure арендатора организации.
  • Он имеет функцию загрузки / скачивания / удаления файла (любого типа) в / из сети.местоположение (nas диски мы называем это), например, \ nas8782 \ xyz \ abc \
  • загрузка / загрузка / удаление работают нормально (см. код ниже).Мы используем библиотеку CloudSdk.Azure, созданную нашей командой Azure.

    • nasClient.UploadAsync
    • nasClient.DownloadAsync
    • nasClient.DeleteAsync
    • nasClient.ListFilesAsync

FileService.cs

using CloudSdk.Azure;

private string userId = ConfigurationManager.AppSettings["userId"].ToString();
    private string userPassword = ConfigurationManager.AppSettings["userPassword"].ToString();
    private string baseNasLocation = ConfigurationManager.AppSettings["baseNasLocation"].ToString();
    string env = ConfigurationManager.AppSettings["env"].ToString().ToUpper();

public async Task Upload(string fileName, string fileToSave, string projectID)
    {
        var nasClient = new NasClient(userId, userPassword);
        var localFiles = new List<string>();
        localFiles.Add(fileToSave);
        await nasClient.UploadAsync(baseNasLocation + env + @"\" + projectID + @"\", localFiles);
}
public async Task Download(string fileToDownload, string projectID)
    {
        var nasClient = new NasClient(userId, userPassword);
        Stream stream2 = nasClient.DownloadAsync(baseNasLocation + env + @"\" + projectID + @"\" + fileToDownload).Result;
        var appPath2 = HostingEnvironment.MapPath("~\\TempUpload");
        var localFullPath2 = string.Format("{0}\\{1}", appPath2, fileToDownload);
        using (var fileStream2 = System.IO.File.Create(localFullPath2))
        {
            stream2.CopyTo(fileStream2);
        }
}


 public async Task Delete(string fileToDelete, string projectID)
    {
        var nasClient = new NasClient(userId, userPassword);
        Task stream2 = nasClient.DeleteAsync(baseNasLocation + env + @"\" + projectID + @"\" + fileToDelete);
}

Я вызываю эти функции по умолчанию.Страница aspx.cs

private void Download(string fileName)
    {
        FileService fObj = new FileService();
        var task = Task.Run(async () => { await fObj.Download(fileName, projectId.ToString()); });
        task.Wait();
    }
 private void Delete(string fileName)
    {
        FileService fObj = new FileService();
        var task = Task.Run(async () => { await fObj.Delete(fileName, projectId.ToString()); });
        task.Wait();
    }
private void Upload(string fileName, string fileToSave)
    {
        FileService fObj = new FileService();
  var task = Task.Run(async () => { await fObj.Upload(fileName, fileToSave, projectId.ToString()); });
        task.Wait();
    }

ISSUE

-Эта библиотека CloudSdk.Azure имеет еще один вызов функции ListFilesAsync, она получает список всех файлов, присутствующих в путипри условии.

Я использую код ниже, чтобы сделать то же самое, но не могу его получить.

Если я вызываю этот метод Fileservice

без асинхронности и ожидания - он запускается, но продолжает работать и никогда не возвращает результат.

public  Task<string> ListFileNames(string projectID)
        {
            var nasClient = new NasClient(userId, userPassword);
            string nasPath = baseNasLocation + env + @"\" + projectID + @"\"; 

            var content =  nasClient.ListFilesAsync(nasPath).Result;
            //return content;
            return JsonConvert.DeserializeObject <Task<string>> (content); 
        }

С помощью асинхронизации и ожидания - выдаетошибка компиляции> 'string' не содержит определения для 'GetAwaiter', и не найдено никакого метода расширения 'GetAwaiter', принимающего первый аргумент типа 'string' (вы пропустили директиву using или ссылку на сборку?)

 public async Task<string> ListFileNames(string projectID)
        {
            var nasClient = new NasClient(userId, userPassword);
            string nasPath = baseNasLocation + env + @"\" + projectID + @"\"; 

            var content = await nasClient.ListFilesAsync(nasPath).Result;
            //return content;
            return JsonConvert.DeserializeObject <Task<string>> (content); 
        }

Как я вызываю этот метод со страницы aspx.cs> Как получить результат обратно?

  var task = Task.Run(async () => { await fObj.ListFileNames(projectId.ToString()); });
        task.Wait();

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

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Следующее должно быть вашей реализацией:

  public async Task<string> ListFileNames(string projectID)
    {
        var nasClient = new NasClient(userId, userPassword);
        string nasPath = baseNasLocation + env + @"\" + projectID + @"\"; 

        return await nasClient.ListFilesAsync(nasPath);
    }
  • Нет вызова Result в ожидании вызова
  • Без десериализации до Task<string>, результат автоматически обернется в Task<T>
  • Result, Wait блокируют вызовы для Task и не встроены в Async-Await, поскольку операции выполняются асинхронно. В некоторых случаях вы можете использовать GetAwaiter().GetResult(), но я не нахожу слишком много вариантов его использования.
  • Асинхронный метод может иметь тип возвращаемого значения Task или Task<T>, где результат автоматически переносится в дизайн.

Способ работы Async Await предназначен для истинной операции на основе Async / IO, он освобождает контекст вызова, а операция происходит в фоновом режиме, что повышает масштабируемость системы

0 голосов
/ 10 мая 2018

Вы можете использовать Task.Result, чтобы получить результат задачи синхронно.

string result = Task.Result;

Кроме того, вы не должны использовать JsonConvert.DeserializeObject для создания Задачи.Я не уверен, что вы пытаетесь сделать там.Вы можете использовать JObject, который обеспечивает динамический доступ.

...