尝试创build资产时出现System.NotSupportedException
我正尝试在Azure
托pipe的API Service
中使用Azure MediaService API
和Azure Storage API
。
用户将videostream作为HttpPost
发送到服务,该服务将video作为Blob存储在我的存储帐户中,媒体服务对video进行编码,并且当video的链接准备就绪时,将其返回给用户。
但是,当我试图创build一个Asset
System.NotSupportedException
引发的消息:
抛出的exception:Microsoft.Data.Services.Client.dll中的“System.NotSupportedException”抛出exception:mscorlib.dll中的“System.NotSupportedException”iisexpress.exe错误:0:exception= System.NotSupportedException:此目标框架无法启用直接枚举数据服务查询。 这是因为枚举自动向数据服务发送同步请求。 由于此框架仅支持asynchronous操作,因此您必须调用BeginExecute和EndExecute方法来获取支持枚举的查询结果。
我正在使用以下版本的所需的依赖关系:
Microsoft.Data.Services.Client - 5.6.2.0 Microsoft.WindowsAzure.MediaServices.Client - 3.0.0.8 Microsoft.WindowsAzure.Storage - 3.1.0.1
这是我的代码:
CloudMediaContext _context; IAsset asset; using (MemoryStream Ms = new MemoryStream(data.Data)) { _context = new CloudMediaContext("accountName", "accountKey"); asset = await _context.Assets.CreateAsync("blobContainerName", AssetCreationOptions.None,CancellationToken.None); ... ... }
data.Data
包含video的byte[]
。 CreateAsync
被调用时引发exception。 我试过_context.Assets.Create
没有运气。
重要的编辑
我创build了一个新的控制台应用程序,使用了我在API服务中使用的代码,并成功执行了它。 所以问题在于API服务。
这是我的类和方法的定义
public class UploadController : ApiController { [HttpPost] public async Task<string> PostUpload(VideoData data) { ... ... }
任何替代可能吗?
我能够使用.NET 4.6.1和下面的nuget包创build一个工作演示:
-
windowsazure.mediaservices v3.6.0.0
- 创build一个全新的MVC应用程序。
- 在
web.config
添加一些依赖程序集(如果不存在) https://social.msdn.microsoft.com/Forums/azure/en-US/eb05a115-36b2-47a5-b464-3220548a5de9/upgrade-to-media -Services-SDK-20-错误与-microsoftpracticestransientfaulthandlingcore?论坛= MediaServices - 添加一个post操作
[HttpPost] public async Task<string> PostUpload() { var bytes = System.Text.Encoding.UTF8.GetBytes("Test"); var data = new VideoData { Data = bytes }; CloudMediaContext _context; using (MemoryStream ms = new MemoryStream(data.Data)) { var accountName = "accountName"; var accountKey = @"primaryaccessKey"; _context = new CloudMediaContext(accountName, accountKey); var asset = await _context.Assets.CreateAsync("myjblobassets", AssetCreationOptions.None, CancellationToken.None); //... do something with asset and ms ... } return "http://my-link"; }
*注意:由于我们没有演示上传部分,因此任何字节都可以,因此我们确保创build媒体服务资产。
- 在索引视图中添加一个HTML
form
并提交button
,指向这个post操作,运行它并运行!
注意:在NAME中,input新帐户的名称。 媒体服务帐户名称全部为小写字母或不带空格的字母,长度为3至24个字符。 https://azure.microsoft.com/en-us/documentation/articles/media-services-dotnet-get-started/
我不能告诉你为什么它不能正常工作。 但是我认为这个问题比在Azure API中更容易发现你的函数的构造。
应该这样做:
// Important is the return value of the function: public async Task<IAsset> CreateAssetBlobAsync(CancellationToken token) { var asset = await _context.Assets.CreateAsync("blobContainerName", AssetCreationOptions.None, CancellationToken.None); // or your 'token' return asset; }
而这个asynchronous函数应该像这样调用:
public static async Task ProcessNewBlobAsync() { // ... var asset = await CreateAssetBlobAsync(token); // ... }
我认为这个问题将是你 。 using
声明
事实上, MemoryStream
的Read/Write Async
方法实际上并不提供任何一种真正的asynchronous实现。 这意味着他们总是会同步的。
(但是你没有调用其中的任何一个,我担心它可能是asynchronous方法的同步包装,所以它会调用API同步而不是asynchronous,这只是一个想法。
我build议避免使用async
来防止死锁 。
你可以尝试打电话给方法吗?
Task<IAsset> CreateAsync(string assetName, string storageAccountName, AssetCreationOptions options, CancellationToken cancellationToken)
并传递与媒体服务关联的默认存储帐户名称。 在你的例子中,你正在调用查询默认存储帐户名称的方法。 查询存储帐户已经不是asynchronous的,这是一个错误。 此存储帐户查询发生一次每个上下文不生成服务器上的负载。 如果您可以在应用程序初始化过程中进行查询并在以后创build资产调用中使用它,那将会很好。
我希望“blobContainerName”是你发布这个问题时写的一个模拟吗? 大写字母和blob容器不要混合:)