3

C# 的TaskConfigureAwait(false)可以防止与(例如)UI 线程同步,这并不总是必要的:http: //msdn.microsoft.com/en-us/magazine/hh456402.aspx

在 .NET 中,我相信只能有一个SynchonizationContext,因此很清楚Task应该在哪个线程池上继续执行它。
对于库,当您不能假设用户在 webrequest(在 .NETHttpContext.Current.Items流中)、命令行(普通多线程)、XAML/Windows 窗体(单个 UI 线程)中时,使用它几乎总是更好ConfigureAwait(false),所以服务员知道它可以只在用于调用 Waiter 的任何线程上执行延续(如果您在库中执行阻塞代码,这可能会导致启动初始工作负载的线程池上的线程饥饿,这只是不好的,假设我们不这样做'不要那样做)。
关键是从库的角度来看,您不想使用调用者线程池中的线程来同步延续,您只希望延续在任何线程上运行。例如,这节省了上下文切换并保持 UI 线程的负载。

在 Scala 中,对于 Futures 上的每个操作(即映射),您需要一个ExecutionContext(隐式传递)。这使得管理线程池非常容易,我更喜欢 .NET 有点奇怪TaskFactory的方式(似乎没有人使用,他们只使用默认值TaskFactory)。

我的问题是,Scala 是否存在与 .NET 相同的问题,即有时不必要的上下文切换,如果是这样,是否有类似于 的方法ConfigureAwait来解决此问题?

我在 Scala 中找到的具体示例,我对此感到疑惑:

def trace[T](message: => String)(block: => Future[T]): Future[T] = {
  if (!logger.isTraceEnabled) block
  else {
    val startedAt = System.currentTimeMillis()
    block.map { result =>
      val timeTaken = System.currentTimeMillis() - startedAt
      logger.trace(s"$message took ${timeTaken}ms")
      result
    }
  }
}

我正在使用 play 并且我通常会导入 play 的默认值,implicit ExecutionContext。上的地图block需要在执行上下文中运行。

如果我在库中编写这段 Scala 并添加一个隐式参数executionContext

def trace[T](message: => String)(block: => Future[T])(implicit executionContext: ExecutionContext): Future[T] = {

而不是在库中导入 play 的默认值ExecutionContext

4

0 回答 0