【发布时间】:2020-06-24 12:10:49
【问题描述】:
经验: 长期使用 .Net 和 VB (C#)。使用 Azure、Async/Await 和多线程的时间不会太长。
问题摘要: 我写了一个桌面(基于表单),概念证明来上传/列出和检索 Azure Block Store 中的视频。这最初是使用 Sync 调用,但后来我添加到 PoC 以使用 Async 调用。一切都很好,我得到了我认为的“预期行为”。异步版本允许我使用“正在下载”填充标签,然后在下载完成时清除该标签。在最终解决方案中,它将允许网页完全加载,而无需任何时间下载视频材料。 当我开始将我的 PoC 代码移动到 .NET web 应用程序中时,问题就出现了。在这个项目中,相同的代码挂在第二个 Async 方法称为 [Await download.Content.CopyToAsync(downloadFileStream)] 处。这样,我的意思是它永远不会被评论执行点:C。
Imports System.IO
Imports Azure.Storage.Blobs
Imports Azure.Storage.Blobs.Models
Imports System.Threading.Tasks
Public Class frmBlockStore
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/concepts/async/
' https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-dotnet
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim gWorkingPath As String = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath
Dim sAzFRConnection As String = Environment.GetEnvironmentVariable("AZ_FR_BLOCK_STORAGE_CONNECTION_STRING")
If sAzFRConnection <> "" Then
Dim blobServiceClient As BlobServiceClient = New BlobServiceClient(sAzFRConnection)
' Open an existing container
Dim sFileName As String = "17.5.04.mp4"
Dim containerClient As BlobContainerClient = blobServiceClient.GetBlobContainerClient("media")
If containerClient.Exists Then
' Sync calls that work perfectly...
'Dim blobClient As BlobClient = containerClient.GetBlobClient(sFileName.ToLower)
'Dim download As BlobDownloadInfo = blobClient.Download()
'Dim downloadFileStream As FileStream = File.OpenWrite(gWorkingPath & "DocFiltered_files" & "\" & sFileName)
'download.Content.CopyTo(downloadFileStream)
'downloadFileStream.Close()
Dim lReturn As Task = DownloadVideoAsync(containerClient, sFileName)
' Execution point: A
End If
End If
End Sub
Async Function DownloadVideoAsync(containerClient As BlobContainerClient, sFileName As String) As Task(Of Long)
Dim gWorkingPath As String = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath
Dim downloadFileStream As FileStream = File.OpenWrite(gWorkingPath & "DocFiltered_files" & "\" & sFileName)
Dim blobClient As BlobClient = containerClient.GetBlobClient(sFileName)
Dim download As BlobDownloadInfo = Await blobClient.DownloadAsync()
' Execution point: B
Await download.Content.CopyToAsync(downloadFileStream)
' Execution point: C
Dim lLth As Long = downloadFileStream.Length
downloadFileStream.Close()
Return lLth
End Function
End Class
单击按钮后,先决条件代码会正常执行并继续调用 DownloadVideoAsync。我已经在按钮单击事件中为感兴趣的人包含了有效的等效同步代码,注释掉了。在该函数中,执行继续到“等待 blobClient.DownloadAsync()”。无论如何,此功能似乎永远不会花费很长时间,因为我认为它正在设置下载,而不是执行它。我想有一些 Azure 方面的事情要做,因此调用的异步性质。因此,在执行此语句时,下一个执行点位于执行点:A,即返回到调用例程中。这是意料之中的。之后它在执行点恢复:B。这就是调试器绘制它的全部方式(接受正在发生的事情的多线程性质可能意味着这实际上是并行的?)下一条语句 [Await download.Content.CopyToAsync (downloadFileStream)] 开始执行。我们可以在目标文件目标文件夹中看到,现在存在指定文件名的零字节文件。但是,执行点:C 永远不会到达,并且目标目的地的文件永远不会超过零字节数。
桌面应用程序中几乎相同的同步调用可以完美地工作,如下所示。
Dim lReturn As Task(Of Long) = DownloadVideoAsync(containerClient, "17.5.04.mp4")
Async Function DownloadVideoAsync(containerClient As BlobContainerClient, sFileName As String) As Task(Of Long)
Dim gWorkingPath As String = "C:\Work\Source\Web\FindResponse\WebSource\"
Dim downloadFileStream As FileStream = File.OpenWrite(gWorkingPath & "DocFiltered_files" & "\" & sFileName)
Dim blobClient As BlobClient = containerClient.GetBlobClient(sFileName)
Dim download As BlobDownloadInfo = Await blobClient.DownloadAsync()
Await download.Content.CopyToAsync(downloadFileStream)
Dim lLth As Long = downloadFileStream.Length
downloadFileStream.Close()
Return lLth
End Function
我也许应该补充一点,设置一个实际上设法编译而没有错误和警告的 Web 项目是“具有挑战性的”和耗时的。我建议任何尝试使用 Azure 工具来采用最新版本的 .NET、加载开发版本的 .NET Cord SDK 并使用 NuGet 而不是“dotnet add”来安装所需的包的人。如果您的应用程序较旧,请在每个阶段备份您的源代码,以便您回滚并重新考虑您的选择!
环境详情: 两个应用程序(桌面和 Web)都在 Visual Studio 开发环境中运行,并使用连接字符串连接到 Azure。
Windows 10 家庭版,版本 1903,操作系统版本 18362.719
视觉工作室: 微软 Visual Studio 社区 2017 版本 15.9.13 VisualStudio.15.Release/15.9.13+28307.718 微软 .NET 框架 版本 4.8.03752
安装版本:社区
Visual C++ 2017 00369-60000-00001-AA335 微软 Visual C++ 2017
适用于 Visual Studio 包 8.14.20131.1 的 Application Insights 工具 适用于 Visual Studio 的 Application Insights 工具
ASP.NET AJAX 控件工具包 1.0 ASP.NET AJAX Control Toolkit Visual Studio 集成包
ASP.NET 和 Web 工具 2017 15.9.04012.0 ASP.NET 和 Web 工具 2017
ASP.NET Core Razor 语言服务 15.8.31590 为 ASP.NET Core Razor 提供语言服务。
ASP.NET Web 框架和工具 2017 5.2.61435.0 欲了解更多信息,请访问https://www.asp.net/
Azure 应用服务工具 v3.0.0 15.9.03024.0 Azure 应用服务工具 v3.0.0
Azure 函数和 Web 作业工具 15.9.03024.0 Azure Functions 和 Web 作业工具
C# 工具 2.10.0-beta2-63501-03+b9fb1610c87cccc8ceb74a770dba261a58e39c4a IDE 中使用的 C# 组件。根据您的项目类型和设置,可能会使用不同版本的编译器。
常用 Azure 工具 1.10 提供供 Azure 移动服务和 Microsoft Azure 工具使用的通用服务。
JavaScript 语言服务 2.0 JavaScript 语言服务
JavaScript 项目系统 2.0 JavaScript 项目系统
JavaScript UWP 项目系统 2.0 JavaScript UWP 项目系统
微软 Azure 工具 2.9 适用于 Microsoft Visual Studio 2017 的 Microsoft Azure 工具 - v2.9.20417.1
适用于 Visual Studio 0.4 的 Microsoft 持续交付工具 在 Visual Studio IDE 中简化 Azure DevOps 管道的配置。
Microsoft JVM 调试器 1.0 支持将 Visual Studio 调试器连接到与 JDWP 兼容的 Java 虚拟机
微软图书馆管理器 1.0 轻松将客户端库安装到任何 Web 项目中
基于微软 MI 的调试器 1.0 支持将 Visual Studio 连接到兼容 MI 的调试器
Microsoft Visual C++ 向导 1.0 Microsoft Visual C++ 向导
Microsoft Visual Studio 容器工具 1.1 在目标环境中开发、运行和验证您的 ASP.NET Core 应用程序。 F5 将您的应用程序直接放入带有调试功能的容器中,或 CTRL + F5 编辑和刷新您的应用程序,而无需重新构建容器。
Microsoft Visual Studio VC 包 1.0 Microsoft Visual Studio VC 包
MLGen 软件包扩展 1.0 MLGen 包 Visual Studio 扩展详细信息
适用于 Visual Studio 1.2.8 的 MySQL MySQL 的数据设计和管理工具。版权所有 (c) 2007、2018,Oracle 和/或其附属公司。保留所有权利。
NuGet 包管理器 4.6.0 Visual Studio 中的 NuGet 包管理器。有关 NuGet 的更多信息,请访问http://docs.nuget.org/。
适用于 Visual Studio 2017 的 Office 开发人员工具 ENU 15.0.28224.00 适用于 Visual Studio 2017 的 Microsoft Office 开发人员工具 ENU
ProjectServicesPackage 扩展 1.0 ProjectServicesPackage Visual Studio 扩展详细信息
资源包扩展 1.0 ResourcePackage Visual Studio 扩展详细信息
资源包扩展 1.0 ResourcePackage Visual Studio 扩展详细信息
SQL Server 数据工具 15.1.61906.03120 Microsoft SQL Server 数据工具
TypeScript 工具 15.9.30524.2002 Microsoft Visual Studio 的 TypeScript 工具
Visual Basic 工具 2.10.0-beta2-63501-03+b9fb1610c87cccc8ceb74a770dba261a58e39c4a IDE 中使用的 Visual Basic 组件。根据您的项目类型和设置,可能会使用不同版本的编译器。
适用于 F# 4.5 15.8.0.0 的 Visual F# 工具 10.2。提交哈希:6e26c5bacc8c4201e962f5bdde0a177f82f88691。 适用于 F# 4.5 的 Microsoft Visual F# 工具 10.2
Visual Studio 代码调试适配器主机包 1.0 用于在 Visual Studio 中托管 Visual Studio Code 调试适配器的互操作层
Visual Studio 容器工具 1.0 用于容器的 Visual Studio 工具
适用于通用 Windows 应用程序的 Visual Studio 工具 15.0.28307.718 适用于通用 Windows 应用的 Visual Studio 工具允许您构建单一的通用应用体验,该体验可以覆盖所有运行 Windows 10 的设备:手机、平板电脑、PC 等。它包括 Microsoft Windows 10 软件开发工具包。
工作流管理器工具 1.0 1.0 此软件包包含 Workflow Manager 所需的 Visual Studio 集成组件。
NuGet:
PM> 获取包
Id 版本项目名称
-- -------- ------------
Azure.Core {1.1.0} BlobStore
Azure.Storage.Blobs {12.4.0} BlobStore
Azure.Storage.Common {12.3.0} BlobStore
Microsoft.Bcl.AsyncInterfaces {1.0.0} BlobStore
Microsoft.CodeDom.Providers.DotN... {2.0.1} BlobStore
System.Buffers {4.5.0} BlobStore
System.Diagnostics.DiagnosticSource {4.6.0} BlobStore
System.Memory {4.5.3} BlobStore
System.Numerics.Vectors {4.5.0} BlobStore
System.Runtime.CompilerServices.... {4.5.2} BlobStore
System.Threading.Tasks.Extensions {4.5.2} BlobStore
.NET Core SDK 3.1 已安装。
【问题讨论】:
标签: .net vb.net azure async-await azure-blob-storage