Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.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# 将异步lambda包装到异步方法_C#_Wcf_Asynchronous_Async Await - Fatal编程技术网

C# 将异步lambda包装到异步方法

C# 将异步lambda包装到异步方法,c#,wcf,asynchronous,async-await,C#,Wcf,Asynchronous,Async Await,我正在尝试将我的操作契约包装到try-catch块。问题是我的EF上下文在同一时间范围内被破坏。我猜问题编译器不知道该怎么做。我的catch块也不处理任何异常。对不起,我的英语,我希望我的代码能说明我的意思: private static async Task<T> SurroundWithTryCatch<T>(Action t, T response) where T : BaseResponse { try { await Task

我正在尝试将我的
操作契约
包装到try-catch块。问题是我的EF上下文在同一时间范围内被破坏。我猜问题编译器不知道该怎么做。我的catch块也不处理任何异常。对不起,我的英语,我希望我的代码能说明我的意思:

private static async Task<T> SurroundWithTryCatch<T>(Action t, T response) where T : BaseResponse 
{
    try
    {
        await Task.Run(t);
    }
    catch (Exception e)
    {
        response.Success = false;
        response.Errors.Add(e.Message);
    }
    return response;
}

public async Task<CreateResponse> CreateAsync(CreateRequest request)
{
    var response = new CreateResponse();
    return await SurroundWithTryCatch(async delegate
    {
        var newUser = new ApplicationUser { UserName = request.UserName, Email = request.Email };
        await Database.UserManager.CreateAsync(newUser, request.Password);
        //Some another logic...
        await Database.CommitAsync();
    }, response);
}
private static async Task SurroundWithTryCatch(Action t,t response),其中t:BaseResponse
{
尝试
{
等待任务。运行(t);
}
捕获(例外e)
{
回答:成功=错误;
响应.错误.添加(e.Message);
}
返回响应;
}
公共异步任务CreateAsync(CreateRequest请求)
{
var response=newcreateresponse();
return wait SurroundWithTryCatch(异步委托
{
var newUser=newapplicationuser{UserName=request.UserName,Email=request.Email};
等待Database.UserManager.CreateAsync(newUser,request.Password);
//另一种逻辑。。。
wait Database.CommitAsync();
},回应);
}

CreateAsync
方法第二行中的问题<代码>用户管理器已由GC先前清理。所以我有了
ObjectDisposedException
Database
IUnitOfWork
的实现,由
Autofac
注入您正在打破
Wait
链-
t
不再返回任务。由于您不再有任务,因此执行将在第一个
wait
之后继续,而不是在完成整个方法之后。将
wait
视为
return
-如果您不返回(和
wait
/wait)任务,您将失去同步的机会

相反,您希望传递
Func
,并直接等待它:

private static async Task<T> SurroundWithTryCatch<T>(Func<Task> t, T response) where T : BaseResponse 
{
    try
    {
        await t();
    }
    catch (Exception e)
    {
        response.Success = false;
        response.Errors.Add(e.Message);
    }
    return response;
}

public async Task<CreateResponse> CreateAsync(CreateRequest request)
{
    var response = new CreateResponse();
    return await SurroundWithTryCatch(async () =>
    {
        var newUser = new ApplicationUser { UserName = request.UserName, Email = request.Email };
        await Database.UserManager.CreateAsync(newUser, request.Password);
        //Some another logic...
        await Database.CommitAsync();
    }, response);
}
private static async Task SurroundWithTryCatch(Func t,t response),其中t:BaseResponse
{
尝试
{
等待t();
}
捕获(例外e)
{
回答:成功=错误;
响应.错误.添加(e.Message);
}
返回响应;
}
公共异步任务CreateAsync(CreateRequest请求)
{
var response=newcreateresponse();
return wait SurroundWithTryCatch(异步()=>
{
var newUser=newapplicationuser{UserName=request.UserName,Email=request.Email};
等待Database.UserManager.CreateAsync(newUser,request.Password);
//另一种逻辑。。。
wait Database.CommitAsync();
},回应);
}

Task.Run
也可以运行,但您可能无论如何都不希望这样做-您的代码是异步的,而且(猜测)您正在ASP.NET请求中运行,因此启动任务只是等待另一个任务的结果没有任何好处
Task.Run
用于在单独的线程中执行CPU工作,这是ASP.NET中通常要避免的事情。

您正在打破
wait
链-
t
不再返回任务。由于您不再有任务,因此执行将在第一个
wait
之后继续,而不是在完成整个方法之后。将
wait
视为
return
-如果您不返回(和
wait
/wait)任务,您将失去同步的机会

相反,您希望传递
Func
,并直接等待它:

private static async Task<T> SurroundWithTryCatch<T>(Func<Task> t, T response) where T : BaseResponse 
{
    try
    {
        await t();
    }
    catch (Exception e)
    {
        response.Success = false;
        response.Errors.Add(e.Message);
    }
    return response;
}

public async Task<CreateResponse> CreateAsync(CreateRequest request)
{
    var response = new CreateResponse();
    return await SurroundWithTryCatch(async () =>
    {
        var newUser = new ApplicationUser { UserName = request.UserName, Email = request.Email };
        await Database.UserManager.CreateAsync(newUser, request.Password);
        //Some another logic...
        await Database.CommitAsync();
    }, response);
}
private static async Task SurroundWithTryCatch(Func t,t response),其中t:BaseResponse
{
尝试
{
等待t();
}
捕获(例外e)
{
回答:成功=错误;
响应.错误.添加(e.Message);
}
返回响应;
}
公共异步任务CreateAsync(CreateRequest请求)
{
var response=newcreateresponse();
return wait SurroundWithTryCatch(异步()=>
{
var newUser=newapplicationuser{UserName=request.UserName,Email=request.Email};
等待Database.UserManager.CreateAsync(newUser,request.Password);
//另一种逻辑。。。
wait Database.CommitAsync();
},回应);
}

Task.Run
也可以运行,但您可能无论如何都不希望这样做-您的代码是异步的,而且(猜测)您正在ASP.NET请求中运行,因此启动任务只是等待另一个任务的结果没有任何好处
Task.Run
用于在单独的线程中执行CPU工作,这是ASP.NET中通常要避免的事情。

尝试将
SurroundWithTryCatch(Action t,t response)
替换为
SurroundWithTryCatch(funct t,t response)
返回wait SurroundWithTryCatch(异步代理
with
return wait SurroundWithTryCatch(async()=>
@YacoubMassad)感谢您的快速回复!它很有效!!我在两点钟或更长的时间里都在挣扎。您能解释一下发生了什么并将其作为答案发布吗?尝试用trycatch替换
SurroundWithTryCatch(动作t,t响应)
(Func t,t response)和
return await SurroundWithTryCatch(异步委托
with
return await SurroundWithTryCatch(异步()=>
@YacoubMassad感谢您的快速回复!它很有效!!我在两点钟或更长的时间里一直在挣扎。您能解释一下发生了什么并将其作为答案发布吗?非常感谢!您今天救了我一命!如果我的
T
是前置类型,我能做同样的事情吗?我有一个包装原始类型的想法,但可能是更好的方法。@user3818229我不确定“基元类型”的确切含义。一般来说,泛型可以处理您想要的任何类型;如果您想做一些更具体的事情,可以使用泛型类型约束(正如您在这里所做的)或强制转换。@user3818229那么你是说值类型?包装它们可以很好地用于泛型。诀窍是确保修改的是共享值,而不是复制的值(值类型按值传递给方法,因此它们总是创建副本)。一种方法是使用
ref T
,另一种方法是创建您自己的包装器类。非常感谢!您