Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# using语句内部的Dapper异步查询需要一个开放的可用连接_C#_Asp.net_Asynchronous_Asp.net Web Api_Dapper - Fatal编程技术网

C# using语句内部的Dapper异步查询需要一个开放的可用连接

C# using语句内部的Dapper异步查询需要一个开放的可用连接,c#,asp.net,asynchronous,asp.net-web-api,dapper,C#,Asp.net,Asynchronous,Asp.net Web Api,Dapper,我正在我的项目中使用。我的项目由3层组成。API、业务和存储库层 我希望用户异步查询dapper 下面是每一层的代码 存储库层 public Task<int> ChangeStatus(DriverStatus driverStatus) { using (IDbConnection connection = DapperConnection) { var updateQuery = @

我正在我的项目中使用。我的项目由3层组成。API、业务和存储库层

我希望用户异步查询dapper

下面是每一层的代码

存储库层

public Task<int> ChangeStatus(DriverStatus driverStatus)
        {
            using (IDbConnection connection = DapperConnection)
            {
                var updateQuery = @"UPDATE [dbo].[DriverLocation] Set [Latitude]=@Latitude, [Longitude]=@Longitude, [IsOnline]=@IsOnline Where [DriverId]=@DriverId";
                return connection.ExecuteAsync(updateQuery, new
                {
                    Latitude = driverStatus.Latitude,
                    Longitude = driverStatus.Longitude,
                    IsOnline = driverStatus.IsOnline,
                    DriverId = driverStatus.DriverId
                });
            }
        }
公共任务更改状态(DriverStatus DriverStatus)
{
使用(IDbConnection=DAPPonnection)
{
var updateQuery=@“更新[dbo].[DriverLocation]设置[Latitude]=@Latitude,[Latitude]=@Latitude,[IsOnline]=@IsOnline,其中[DriverId]=@DriverId”;
返回连接.ExecuteAsync(updateQuery,新建
{
纬度=驾驶员状态。纬度,
经度=驾驶员状态。经度,
IsOnline=driverStatus.IsOnline,
driverrid=driverStatus.driverrid
});
}
}
现在我的业务层方法调用上述存储库方法

public Task<int> ChangeStatus(DriverStatus driverStatus)
        {
            try
            {
                //Some Code here.
               return driverRepository.ChangeStatus(driverStatus);
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                return Task.FromResult<int>(0);
            }
        }
公共任务更改状态(DriverStatus DriverStatus)
{
尝试
{
//这里有一些代码。
返回DriverReplicatory.ChangeStatus(driverStatus);
}
捕获(例外情况除外)
{
记录器错误(ex);
返回Task.FromResult(0);
}
}
现在API方法调用业务层方法

public async Task<IHttpActionResult> ChangeStatus(DriverStatus driverStatus)
        {
            ApiResponse apiResponse = new ApiResponse();
            var isUpdated = await driverBl.ChangeStatus(driverStatus);
            if(isUpdated > 0)
            {
                apiResponse.Message = "Driver status changed successfully.";
                return ResponseMessage(Request.CreateResponse(HttpStatusCode.OK, apiResponse));
            }
            else
            {
                apiResponse.Message = "Driver status could not be changed.";
                return ResponseMessage(Request.CreateResponse(HttpStatusCode.BadRequest, apiResponse));
            }

        }
公共异步任务更改状态(DriverStatus DriverStatus)
{
ApiResponse ApiResponse=新的ApiResponse();
var isUpdated=等待驱动程序bl.ChangeStatus(驱动程序状态);
如果(IsUpdate>0)
{
apiResponse.Message=“驱动程序状态已成功更改。”;
返回响应消息(Request.CreateResponse(HttpStatusCode.OK,apiResponse));
}
其他的
{
apiResponse.Message=“无法更改驱动程序状态。”;
返回ResponseMessage(Request.CreateResponse(HttpStatusCode.BadRequest,apiResponse));
}
}
由于我只在API方法中使用了wait关键字,所以我的连接对象可能在返回结果之前就被处理掉了,所以它将我抛出下面的错误

BeginExecutenQuery需要一个开放且可用的连接。这个 连接的当前状态为关闭


如何使用
语句使用dapper的异步方法?

使用async/wait,您需要确保在整个调用堆栈中都使用它

您的回购层应如下所示:

public async Task<int> ChangeStatus(DriverStatus driverStatus)
{
    using (IDbConnection connection = DapperConnection)
    {
        var updateQuery = @"UPDATE [dbo].[DriverLocation] Set [Latitude]=@Latitude, [Longitude]=@Longitude, [IsOnline]=@IsOnline Where [DriverId]=@DriverId";
        return await connection.ExecuteAsync(updateQuery, new
        {
            Latitude = driverStatus.Latitude,
            Longitude = driverStatus.Longitude,
            IsOnline = driverStatus.IsOnline,
            DriverId = driverStatus.DriverId
        });
    }
}
public async Task<int> ChangeStatus(DriverStatus driverStatus)
{
    try
    {
        //Some Code here.
        return await driverRepository.ChangeStatus(driverStatus);
    }
    catch (Exception ex)
    {
        Logger.Error(ex);
        return 0;
    }
}
公共异步任务更改状态(DriverStatus DriverStatus)
{
使用(IDbConnection=DAPPonnection)
{
var updateQuery=@“更新[dbo].[DriverLocation]设置[Latitude]=@Latitude,[Latitude]=@Latitude,[IsOnline]=@IsOnline,其中[DriverId]=@DriverId”;
return wait connection.ExecuteAsync(updateQuery,new
{
纬度=驾驶员状态。纬度,
经度=驾驶员状态。经度,
IsOnline=driverStatus.IsOnline,
driverrid=driverStatus.driverrid
});
}
}
您的BLL层应该如下所示:

public async Task<int> ChangeStatus(DriverStatus driverStatus)
{
    using (IDbConnection connection = DapperConnection)
    {
        var updateQuery = @"UPDATE [dbo].[DriverLocation] Set [Latitude]=@Latitude, [Longitude]=@Longitude, [IsOnline]=@IsOnline Where [DriverId]=@DriverId";
        return await connection.ExecuteAsync(updateQuery, new
        {
            Latitude = driverStatus.Latitude,
            Longitude = driverStatus.Longitude,
            IsOnline = driverStatus.IsOnline,
            DriverId = driverStatus.DriverId
        });
    }
}
public async Task<int> ChangeStatus(DriverStatus driverStatus)
{
    try
    {
        //Some Code here.
        return await driverRepository.ChangeStatus(driverStatus);
    }
    catch (Exception ex)
    {
        Logger.Error(ex);
        return 0;
    }
}
公共异步任务更改状态(DriverStatus DriverStatus)
{
尝试
{
//这里有一些代码。
返回等待驾驶员返回。更改状态(驾驶员状态);
}
捕获(例外情况除外)
{
记录器错误(ex);
返回0;
}
}

您的问题是您忽略了async并在存储库层中等待使用,当这与using语句结合使用时,将导致不可预测的行为。

调用connection.ExecuteAsync时,您启动了一个依赖于该连接的任务,因此该连接必须保持打开状态,只要该任务未完成,就不应释放该连接。 在您的情况下,您在启动任务后立即返回,并且正在立即处理连接(因为您有一个using语句,该语句将在连接超出范围时立即处理连接),所有这些都发生在任务完成之前。

为了防止在任务完成之前处理连接,您需要使用async和wait关键字“以异步方式等待”操作,并且仅在wait之后从方法返回结果

public async Task<int> ChangeStatus(DriverStatus driverStatus)
{
    using (IDbConnection connection = DapperConnection)
    {
        var updateQuery = @"UPDATE [dbo].[DriverLocation] Set [Latitude]=@Latitude, [Longitude]=@Longitude, [IsOnline]=@IsOnline Where [DriverId]=@DriverId";
        return await connection.ExecuteAsync(updateQuery, new
        {
            Latitude = driverStatus.Latitude,
            Longitude = driverStatus.Longitude,
            IsOnline = driverStatus.IsOnline,
            DriverId = driverStatus.DriverId
        });
    }
}
公共异步任务更改状态(DriverStatus DriverStatus)
{
使用(IDbConnection=DAPPonnection)
{
var updateQuery=@“更新[dbo].[DriverLocation]设置[Latitude]=@Latitude,[Latitude]=@Latitude,[IsOnline]=@IsOnline,其中[DriverId]=@DriverId”;
return wait connection.ExecuteAsync(updateQuery,new
{
纬度=驾驶员状态。纬度,
经度=驾驶员状态。经度,
IsOnline=driverStatus.IsOnline,
driverrid=driverStatus.driverrid
});
}
}
有关该主题的更多信息,请参阅Stephen Cleary的博客文章。

您还有一个错误,在您的业务层中,您的try-catch块未按预期工作,以便从您拥有的异步方法捕获异常:

公共异步任务更改状态(DriverStatus DriverStatus)
{
尝试
{
//这里有一些代码。
返回等待驾驶员返回。更改状态(驾驶员状态);
}
捕获(例外情况除外)
{
记录器错误(ex);
返回0;
}
}

最后一件不相关的事情是,在业务层吞下异常并向上层做出错误陈述真的是一个好主意吗?

在调用过程中,您应该始终使用
async
。@maccettura:然后我必须在API、业务和服务的所有三个位置等待关键字。是吗?是的,这就是
async
/
等待的方式
works@maccettura:对不起,我不是异步概念方面的专家。但是如果使用awa