3

我有一个连接到 WCF 服务的 ASP.NET MVC 3 站点。WCF 服务独立于站点并托管在 Windows 服务中。大多数调用都是同步的,因此等待 WCF 执行它不是问题。

但是,其中一个(已经实现的)调用花费的时间太长了,而且由于它本质上不直接输出任何东西,我想在服务上旋转它并忘记它。

所以我改变了我的代码:

public ViewResult StartSlowCalculation(CalculationOptions calculationOptions)
{
  WcfServiceProxy.DoSlowCalculation(calculationOptions);
  ViewBag.Started = true;
  return View();
}

public ViewResult StartSlowCalculation(CalculationOptions calculationOptions)
{
  Task.Run(() =>
  {
    WcfServiceProxy.DoSlowCalculation(calculationOptions);
  });

  ViewBag.Started = true;
  return View();
}

据我了解,它应该启动一个异步请求,并立即返回。尽管如此,执行是完全同步的,并且 UI 被冻结直到操作结束。

我错过了什么明显的东西?


更新:

另外,请注意,我不希望将服务器实现更改为异步实现,只是为了取消同步对调用站点上服务的调用。

此外,我注意到该StartSlowCalculation方法完成执行,但服务器在服务方法完成执行之前不会返回响应。

WCF 服务代理只是做:

public void DoSlowCalculation(CalculationOptions calculationOptions)
{
   //some logging code
   Channel.DoSlowCalculation(calculationOptions);
}

所以它是完全同步的,但这并不重要,因为它应该在一个独立的线程上执行。

4

2 回答 2

2

一个任务操作能否在调用线程中运行,这取决于taskScheduler 决定。为了帮助TaskScheduler对长时间运行的呼叫做出正确的决定,您可以指定任务创建选项TaskCreationOptions.LongRunning

您可以检查任务操作是否在单独的线程中运行:

int launchedByThreadId = Thread.CurrentThread.ManagedThreadId;
int launchedInThreadId = -1;
Task.Run(() =>
  {
    launchedInThreadId = Thread.CurrentThread.ManagedThreadId;
    WcfServiceProxy.DoSlowCalculation(calculationOptions);
  });

// then compare whether thread ids are different

顺便说一句,您是否使用任何类型的Task.Wait()操作?它也会阻塞调用线程。

编辑:

您可能会发现以下帖子很有趣Task.Factory.StartNew() 是否保证使用另一个线程而不是调用线程?

所以尝试使用Task.Factory.StartNew()并指定取消令牌,即使你不需要它,这听起来很奇怪,但似乎这保证了任务最终不会在调用线程中运行。纠正我如果我错了。

于 2012-12-27T11:32:30.633 回答
0

我以前做过。

最可靠的方法是使用异步控制器,或者更好的是使用独立服务,例如 WCF 服务。

但根据我的经验,我只需要执行“简单”的单行任务,例如审计或报告。

在那个例子中,最简单的方法 - 启动一个任务:

public ViewResult StartSlowCalculation(CalculationOptions calculationOptions)
{
  //Some Synchronous code.

   Task.Factory.StartNew(() =>
  {
    WcfServiceProxy.DoSlowCalculation(calculationOptions);
  });

  ViewBag.Started = true;
  return View();
}

这是一个简单的例子。您可以根据需要启动任意数量的任务、同步它们、在它们完成时收到通知等。

有关更多详细信息,您可以查看此链接。

https://msdn.microsoft.com/en-us/library/dd321439(v=vs.110).aspx

于 2016-04-07T14:42:01.703 回答