使用await和async返回字符串列表

时间:2018-05-10 07:06:08

标签: c# azure async-await

  • 我在组织租户azure环境中部署了一个ASP.NET(4.5)网站。
  • 它具有向/从网络位置上载/下载/删除文件(任何类型)的功能(我们称之为nas驱动器),例如\ nas8782 \ XYZ \ ABC \
  • 上传/下载/删除工作正常(请参阅下面的代码)。我们使用由Azure团队创建的CloudSdk.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);
}

我从default.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();
    }

问题

- 这个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); 
        }

使用Async和await - 它会抛出编译错误&gt;  '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页面调用此方法&gt;如何获得结果?

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

很抱歉这个长期问题,我只是想尽可能多地描述一下。 我是新手,等待和异步,非常感谢所有的帮助。

2 个答案:

答案 0 :(得分:1)

以下是您的实施:

Result
  • 在等待通话中未拨打Task<string>
  • 没有反序列化到Task<T>,它会自动将结果包装在Result
  • WaitTask阻止了对GetAwaiter().GetResult()的调用,而不是与Async-Await内联,因为操作是异步进行的。在少数情况下,您可以使用Task,但我找不到太多的用例。
  • 异步方法的返回类型可以是Task<T>lambda,其中结果会自动换行设计。

Async Await方式适用于真正的基于Async / IO的操作,它将释放调用上下文,同时操作在后台进行,从而提高系统可扩展性

答案 1 :(得分:0)

您可以使用Task.Result以同步方式获取Task的结果。

string result = Task.Result;

此外,您不应使用JsonConvert.DeserializeObject来创建任务。我不确定你在那里做什么。您可以使用允许动态访问的JObject。