Specflow 测试用例死锁

Specflow test case deadlocks

我在specflow中写了一个测试用例如下:

[Given(@"I have removed entity")]
    public async Task GivenIHaveRemovedEntity(Table table)
    {
        var employee = table.CreateInstance<TableGeneralInfoDto>();
        var schemas = await DataCatalogHooks.SchemasController.Get();
        var schema = schemas.Value.First(x => x.Name != null &&
            x.Name.Equals("BATCH_TEST", StringComparison.CurrentCultureIgnoreCase));
        var objectTypes = await DataCatalogHooks.ObjectTypesController.Get();
        var objectType = objectTypes.Value.First(x =>
            x.Name.Equals("Table", StringComparison.CurrentCultureIgnoreCase)
        );
        employee.SchemaId = schema.Id;
        employee.SystemName = string.Concat(schema.Name, ".", employee.ObjectName);
        employee.ObjectTypeId = objectType.Id;
        _scenarioContext["employee"] = employee;
        try
        {
            var entity = await DataCatalogHooks.TablesController.Get(employee.SystemName);
            await DataCatalogHooks.TablesController.Delete(entity.Value.Id);
        }
        catch { }
    }

TablesController.Delete() 方法作为异步方法调用:

public async Task DeleteAsync(string id)
    {
        try
        {
            var relations = new List<DomainModels.Relation>();
            relations.AddRange(_relationRepository.GetBySourceTableIdAsync(id).GetAwaiter().GetResult());
            relations.AddRange(_relationRepository.GetByReferenceTableIdAsync(id).GetAwaiter().GetResult());
            await _relationRepository.Delete(relations);
            await _client.DeleteAsync(id);
        }
        catch (Exception e)
        {
            Validation.ExceptionManager.ThrowException(new Exception(e.Message));
            throw;
        }
    }

并且此方法内部调用 http 请求如下:

public async System.Threading.Tasks.Task<SwaggerResponse<EntityCollection>> GetEntityCollectionAsync(string idOrName, string tenantId, System.Threading.CancellationToken cancellationToken)
    {
            var urlBuilder_ = new System.Text.StringBuilder();
            urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/v1.0/{tenantId}/collections/{idOrName}");
            urlBuilder_.Replace("{idOrName}", System.Uri.EscapeDataString(ConvertToString(idOrName, System.Globalization.CultureInfo.InvariantCulture)));
            urlBuilder_.Replace("{tenantId}", System.Uri.EscapeDataString(ConvertToString(tenantId, System.Globalization.CultureInfo.InvariantCulture)));

            var client_ = _httpClient;
            try
            {
                using (var request_ = new System.Net.Http.HttpRequestMessage())
                {
                    request_.Method = new System.Net.Http.HttpMethod("GET");
                    request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json"));

                    var url_ = urlBuilder_.ToString();
                    request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
              
                    var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                    try
                    {
                        var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
                        if (response_.Content != null && response_.Content.Headers != null)
                        {
                            foreach (var item_ in response_.Content.Headers)
                                headers_[item_.Key] = item_.Value;
                        }

                        var status_ = ((int)response_.StatusCode).ToString();
                        if (status_ == "200")
                        {
                                var objectResponse_ = await ReadObjectResponseAsync<EntityCollection>(response_, headers_).ConfigureAwait(false);
                                return new SwaggerResponse<EntityCollection>((int)response_.StatusCode, headers_, objectResponse_.Object);
                            }
                        return new SwaggerResponse<EntityCollection>((int)response_.StatusCode, headers_, default(EntityCollection));
                    }
                    finally
                    {
                        if (response_ != null)
                            response_.Dispose();
                    }
                }
            }
            finally
            {
            }

    }

此方法returns结果成功(200)。但在执行此方法后,单元测试继续旋转。没有错误或成功结果显示。 如果我从招摇中调用 Delete API,它工作正常。

.GetAwaiter().GetResult()的用法;在某些情况下,可能会使管理同步上下文的线程死锁,并通过上下文本身死锁。

我删除了 GetAwaiter().GetResult() 并使方法异步。这解决了问题