2

出于测试目的,我直接在.cshtml页面的剃刀块内使用它。

@functions{
    public class Inline
    {
        public HttpResponseBase r { get; set; }
        public int Id { get; set; }
        public List<System.Threading.Tasks.Task> tasks = new List<System.Threading.Tasks.Task>();

        public void Writer(HttpResponseBase response)
        {
            this.r = response;
            tasks.Add(System.Threading.Tasks.Task.Factory.StartNew(
                    () =>
                    {
                        while (true)
                        {
                            r.Write("<span>Hello</span>");
                            System.Threading.Thread.Sleep(1000);
                        }
                    }
            ));
        }
    }
}

@{
    var inL = new Inline();
    inL.Writer(Response);
}

我曾期望它每秒写一次带有文本“Hello”的跨度。它有时会写一次“Hello”,但不是每次甚至大部分时间。为什么这个任务没有长时间运行?

4

2 回答 2

3

您看到不同结果的原因是因为任务正在异步运行,并且如果响应对象在您的任务有机会写入它之前完成,则任务将引发异常并且它将终止您可以这样做的唯一方法是如果您在 Writer() 方法的末尾添加 Task.WaitAll() 。

这将起作用,但页面不会停止加载内容。

this.r = response;
tasks.Add(System.Threading.Tasks.Task.Factory.StartNew(
        () =>
        {
            while (true)
            {
                r.Write("<span>Hello</span>");
                r.Flush(); // this will send each write to the browser
                System.Threading.Thread.Sleep(1000);
            }
        }

));

//this will make sure that the response will stay open
System.Threading.Tasks.Task.WaitAll(tasks.ToArray());
于 2012-11-20T22:49:49.127 回答
1

这是另一个使用自定义 ActionResult 的选项,它首先处理控制器(默认结果),然后完成它开始任务。

public class CustomActionResult:ViewResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        base.ExecuteResult(context);
        var t =  Task.Factory.StartNew(() =>
             {

                  while (true)
                   {
                      Thread.Sleep(1000);
                      context.HttpContext.Response.Write("<h1>hello</h1>");
                      context.HttpContext.Response.Flush();
                   }
            });

        Task.WaitAll(t);
    }
}

在您的控制器中

public class HomeController : Controller
{
    public ActionResult Index()
    {
       return new CustomActionResult();
    }
}
于 2012-11-21T03:03:04.980 回答