2016-11-04 43 views
0

我目前正在做一个ASP.NET MVC(C#)项目。我有一个名为“index”的控制器方法正在使用Web服务,并且此控制器的方法将返回一个值。下面是代码:ASP.NET MVC中的背景计算(C#)

public ActionResult index() 
{ 

    ContactlessTerminal.wsContactlessTerminal objContactlessTerminal = new ContactlessTerminal.wsContactlessTerminal(); 
     string strMessage = objContactlessTerminal.fnMakeContactlessPayment(); 

     if (strMessage.Equals("00")) 
     { 
      ViewBag.Message = "00"; 

     } 
     else if(strMessage.Equals("11")) 
     { 
      ViewBag.Message = "11"; 
     } 

    return View(); 
} 

“索引”视图将检索由控制器的索引方法返回的ViewBag的值,然后在“索引”视图将显示ViewBag的值。 但是,有一些性能问题。 Web服务的消耗时间太长,因此需要一些时间才能使“索引”视图加载完成。

所以我试图通过在另一个线程中放置“正在使用Web服务的代码”来修改代码。下面是代码:

  public ActionResult index() 
     { 
       Thread thread = new Thread(testing); 
       thread.Start(); 
       return View(); 
      } 

      public void testing() 
      { 
        ContactlessTerminal.wsContactlessTerminal objContactlessTerminal = new ContactlessTerminal.wsContactlessTerminal(); 
       string strMessage = objContactlessTerminal.fnMakeContactlessPayment(); 

      if (strMessage.Equals("00")) 
      { 
       ViewBag.Message = "00"; 

      } 
      else if(strMessage.Equals("11")) 
      { 
      ViewBag.Message = "11"; 
      } 


      } 

然而,“指数”视图将无法检索由控制器作为索引视图的
指数方法返回的ViewBag就已经完成加载整个页面之前, Web服务的消耗完成。 基本上,首先,我想在索引视图中显示一个加载“GIF”,以表明它正在处理背景中的东西。当Web服务消耗完成时,索引视图将显示控制器方法返回的viewbag值。

任何人都可以告诉我如何在后台运行“测试”方法,并在Web服务使用完成后,它会通知“索引”视图显示由控制器的索引方法返回的ViewBag。

+2

您不能创建_asynchronous_服务器端,因为视图将(可能)在作业完成之前呈现并返回(与联系WS相比,渲染视图的时间应该可以忽略不计)。你应该做的是使它成为异步客户端。渲染没有该内容的视图,并从客户端开始AJAX调用以收集所需的数据(最终,您可以使用局部视图渲染服务器端) –

+0

1简单视图,不带api调用。 2 ajax调用视图返回一个部分(在您的mvc控制器上)3部分视图,返回api调用的结果 –

+0

或者,查看[signalr](https://www.asp.net/signalr/overview/入门/介绍信号) –

回答

-2

您可以在.Net中使用async模式。例如:

private Task<string> MakeContactlessPaymentAsync() 
{ 
    TaskCompletionSource<string> tcs = new TaskCompletionSource<string>(); 
    Task.Run(() => 
    { 
     ContactlessTerminal.wsContactlessTerminal objContactlessTerminal = 
       new ContactlessTerminal.wsContactlessTerminal(); 
     var strMessage = objContactlessTerminal.fnMakeContactlessPayment(); 
     tcs.SetResult(strMessage); 
     }); 
    return tcs.Task; 
} 

public async Task<ActionResult> GizmosAsync() 
{ 
    var result = await MakeContactlessPaymentAsync();  
    return View(result); //return the string as a model for that view 
} 

EDIT

More info on MVC async

+0

这是如何帮助您渲染视图,然后根据异步结果更新视图? – Charleh

+0

这是对.NET中异步编程如何工作的完全误解。我建议你检查一下它是如何工作的,并注意不要在未来传播有关它的错误信息:异步非常困难,没有不良信息。 – mason

+0

@mason你能更具体吗?我见过像MVC中使用的方法,没有问题。 –

-1

为您运行独立线程的目的是什么?如果您无法立即返回视图并必须等待任务的结果,那么在后台运行它没有意义。

如果你想释放一些资源(即线程),如果你的长期运行的进程正在等待通过网络的一些服务,你必须让你的控制器动作异步和一个单独的任务运行后台线程,如:

return await Task.Run(testing()); 

如果你做一些繁重的计算或不惯于打扰,你可以使用

Task.Run(testing()).Wait(); 

虽然会有这样做真的如我之前提到的没有意义的。

如果你真的想在客户端实现更新,你只需要进行普通的web api调用,并从客户端使用AJAX进行调用,最好使用Knockout,Angular,React等框架。