C# 在这个父方法中,如果没有异步修饰符,我怎么能等待一个异步方法呢?

C# 在这个父方法中,如果没有异步修饰符,我怎么能等待一个异步方法呢?,c#,.net-4.5,async-await,C#,.net 4.5,Async Await,我有一个我想等待的方法,但我不想造成多米诺效应,认为任何东西都可以调用这个调用方法并等待它。例如,我有以下方法: public bool Save(string data) { int rowsAffected = await UpdateDataAsync(data); return rowsAffected > 0; } 我打电话: public Task<int> UpdateDataAsync() { return Task.Run(() =>

我有一个我想等待的方法,但我不想造成多米诺效应,认为任何东西都可以调用这个调用方法并等待它。例如,我有以下方法:

public bool Save(string data)
{
   int rowsAffected = await UpdateDataAsync(data);
   return rowsAffected > 0;
}
我打电话:

public Task<int> UpdateDataAsync()
{
  return Task.Run(() =>
  {
    return Data.Update(); //return an integer of rowsAffected
  }
}
公共任务UpdateDataAsync()
{
返回任务。运行(()=>
{
return Data.Update();//返回一个整数rowsAffected
}
}
这将不起作用,因为我必须在
Save()
的方法签名中添加“async”,然后我不能返回
bool
我必须使它成为
Task
,但我不希望任何人等待
Save()
方法


有没有一种方法可以暂停代码执行,比如等待,或者在没有异步修饰符的情况下以某种方式等待此代码?

编辑:这个答案是在添加任务之前。运行。有了这个额外的上下文,最好将场景描述为“不要这样做”


您可以访问
.Result
或使用
.Wait()
,但首先需要知道任务是如何实现的。特别是,您需要知道它是否使用同步上下文。这一点很重要的原因是,如果使用同步上下文,可能会立即死锁,因为某些同步上下文需要完全退出调用上下文(例如,MVC的同步上下文需要离开控制器的操作方法)

要防止这种情况很难,但您可能应该始终通过调用
.Wait()
,显式指定超时,以防万一

在这个父方法中,如果没有异步修饰符,我怎么能等待一个异步方法呢

这有点像在问“如何使用C#编写应用程序而不依赖于任何类型的.NET运行时?”

简短回答:不要那样做

实际上,您在这里所做的是采用一个自然同步方法(
Update
),通过在线程池线程(
UpdateDataAsync
)上运行它来使它看起来是异步的,然后您想要阻止它,使异步方法看起来是同步的(
Save
)。严重的红色标志

我建议你仔细研究斯蒂芬·图布(Stephen Toub)著名的两篇博文和两篇文章。这两个问题的答案都是“不”,尽管斯蒂芬·图布(Stephen Toub)解释了几种选择,如果你真的必须这样做的话


“真的必须”应该保留给应用程序级别。我假设这些方法(
Update
UpdateDataAsync
,和
Save
)位于应用程序的不同层(例如,数据/数据服务/视图模型)。数据/数据服务层不应进行同步/异步转换。视图模型(特定于应用程序)level是唯一有理由进行这种转换的工具,而且只能作为最后的手段。

谢谢,我使用的是Task.Run-我更新了我的问题以显示第二个问题method@Neal在编辑时,我会说“不要那样做”-你毫无理由地添加了一个线程。你也可以在线程上做这项工作,而这个线程将被等待。@Neal:Marc是绝对正确的;本质上你在这里做的是雇佣一个人代表你等待,然后等待他们完成他们的工作,这是代表你等待。你不会雇佣一个人来完成任务在现实生活中这样做,所以不要在这里这样做。如果你需要同步等待任务完成,那么就这样做;如果你想在等待时继续工作,那么就等待它。如果你给我访问一个阻止我的线程的
Save
方法,从而迫使我将调用包装在
任务中,我会非常恼火ode>,这正是您本来可以首先返回给我的内容。我只是说。如果我正在编写一个测试用例,将内容放入数据库(使用异步驱动程序),该怎么办然后立即把它读出来?只是说,同步编程有合法的用例。@Hypershadsy:为什么不能异步进行呢?你可以编写异步测试用例?@Hypershadsy:是的。所有主要的单元测试框架(xUnit、MSTest、NUnit)都支持
异步任务
单元测试方法。