【问题标题】:Problems for create new DocumentDB documents in async in C#在 C# 中异步创建新 DocumentDB 文档的问题
【发布时间】:2016-02-11 22:35:04
【问题描述】:

我刚开始使用 DocumentDB,所以我下载了 .NET SDK。按照从 Azure 网站下载的使用示例,我正在尝试创建一些文档以保存到 DocumentDB。示例代码如下

   public static void Main(string[] args)
    {
        try
        {
            GetStartedDemo().Wait();
        }
        catch (DocumentClientException de)
        {
            // omissis
        }
    }
    private static async Task GetStartedDemo()
    {
        var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey);

        Family andersonFamily = new Family
        {
            Id = "AndersenFamily",
            LastName = "Andersen",
            Parents = new Parent[] {
                new Parent { FirstName = "Thomas" },
                new Parent { FirstName = "Mary Kay"}
                },
            Children = new Child[] {
                    new Child
                    {
                        FirstName = "Henriette Thaulow",
                        Gender = "female",
                        Grade = 5,
                        Pets = new Pet[] {
                            new Pet { GivenName = "Fluffy" }
                        }
                    }
                },
            Address = new Address { State = "WA", County = "King", City = "Seattle" },
            IsRegistered = true
        };

        await client.CreateDocumentAsync("dbs/" + database.Id + "/colls/" + documentCollection.Id, andersonFamily);

        client.Dispose();
    }

此代码运行良好。我的代码几乎相同,除了我传递的用于将 JSON 保存到 DB 中的类。它总是在线停止

await client.CreateDocumentAsync("dbs/" + database.Id + "/colls/" + coll.Id, this);

我的整个代码如下

public static async Task Save(int UserId, int productID, string code, string language, string dataOraLettura, string longitudine, string latitudine, string nazione_lettura)
    {
        CultureInfo ciEN = CultureInfo.GetCultureInfo("en-US");
        CodeType ScannedCode = new CodeType
        {
            Code = code,
            ProductId = productID,
            ScanLog = new List<CodeType.ScanDataType>()
        };
        ScannedCode.ScanLog.Add(new CodeType.ScanDataType
        {
            Location = new Microsoft.Azure.Documents.Spatial.Point(double.Parse(longitudine, ciEN.NumberFormat), double.Parse(latitudine, ciEN.NumberFormat)),
            ScanType = CodeType.ScanDataType.eScanType.Alert,
            UserId = UserId.ToString(),
            TimeStamp = long.Parse(DateTime.Now.ToString("yyyyMMddHHmmssffff"))
        });
        await ScannedCode.AddAsync();

    }

   public async Task AddAsync()
    {
        using (DocumentClient client = new DocumentClient(new Uri(WebConfigurationManager.AppSettings["DbURI"]), WebConfigurationManager.AppSettings["DbKEY"]))
        {
            var CodeDocuments = client.CreateDocumentQuery<CodeType>("dbs/" + database.Id + "/colls/" + coll.Id).Where(a => a.Code == this.Code).ToArray();
            if (CodeDocuments.Length == 0)
                await client.CreateDocumentAsync("dbs/" + database.Id + "/colls/" + coll.Id, this);
        }
    }

似乎是异步任务阻塞,它没有将控制权交还给调用者,然后继续循环执行。

【问题讨论】:

  • Buncha 小事:ScannedCode.AddAsync() 似乎不是静态的,但它却是这样调用的。你确定你没有超载吗?在提取之前,您需要重复多少次“dbs/.../colls/”模式?如果您在某个方法上有 20 个参数,那么您肯定错过了一个 - 已经将它们放在一个类中。不要跟随示例如何隐藏异常
  • @StenPetrov 这不是代码审查; OP询问了一个异步问题。无需对编码风格提出批评。
  • ScannedCode.AddAsync() 似乎不是静态的,这是我首先要检查的。这个问题本身需要审查,没有足够的信息可以继续......在某些情况下,如果 OP 要重构他们自己的代码,他们会自己发现错误。你的观点很好,因此我的回复是评论,而不是答案
  • 尝试将await client.CreateDocumentAsync更改为client.CreateDocumentAsync(...).Result

标签: c# azure azure-cosmosdb


【解决方案1】:

正确,您有一个异步阻塞另一个异步的经典案例。 您应该在 await ScannedCode.AddAsync(); 上将 ConfigureAwait 设置为 false;

 await ScannedCode.AddAsync().ConfigureAwait(false);

这使它在线程池线程而不是 ASP.NET 请求上下文中恢复。

您可以阅读下面的文章http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html,它很好地解释了这一点以及使用异步代码时的其他最佳实践。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    • 2011-07-27
    相关资源
    最近更新 更多