PushStreamContent Web API

时间:2016-02-17 14:34:56

标签: c# asp.net-web-api

我正在尝试将我的数据从Web API推送到客户端,因此我在Web API中使用PushStreamContent。 我的数据都是学生存在于数据库中。

public HttpResponseMessage GetAll()
    {
        HttpResponseMessage response = new HttpResponseMessage();
        var students = _symboleService.GetAll();
        response.Content = new PushStreamContent((students, httpContent, context) =>
        {
            OnStreamAvailable(students, httpContent, context);
        }, "text/plain");
        return response;

    }

    private void OnStreamAvailable(Stream stream, HttpContent content,TransportContext context)
    {
        StreamWriter responseStreamWriter = new StreamWriter(stream);
        clients.Add(responseStreamWriter);
    }

但是这条线上的“学生”出现了错误:

response.Content = new PushStreamContent((students, httpContent, context) =>
  

无法在此范围内声明名为“students”的本地或参数   因为该名称用于封闭的本地范围来定义   本地或参数

更新我的观点是将数据推送到客户端, 经过一些修改,这是我的代码,但它在线显示错误,

var students = _symboleService.GetAll();
  

非静态字段,方法或者需要对象引用   属性'SymbolesController._symboleService'

private static readonly Lazy<Timer> _timer = new Lazy<Timer>(() => new Timer(TimerCallback, null, 0, 1000));
    private static readonly ConcurrentDictionary<StreamWriter, StreamWriter> _outputs = new ConcurrentDictionary<StreamWriter, StreamWriter>();

    public HttpResponseMessage GetAll()
    {
        HttpResponseMessage response = new HttpResponseMessage();
        response.Content = new PushStreamContent((responseStream, httpContent, context) =>
        {
            StreamWriter responseStreamWriter = new StreamWriter(responseStream);

            _outputs.TryAdd(responseStreamWriter, responseStreamWriter);

        }, "text/plain");

        Timer t = _timer.Value;

        return response;
    }



    // Runs every second after the first request to this controller and
    // writes to the response streams of all currently active requests
    private static void TimerCallback(object state)
    {

        foreach (var kvp in _outputs.ToArray())
        {
            StreamWriter responseStreamWriter = kvp.Value;

            try
            {
                var students = _symboleService.GetAll();
                responseStreamWriter.Write(students);
                responseStreamWriter.Flush();
            }
            catch { }
        }
    }

顺便说一句,如果我通过DateTime更改学生。现在,它可以工作:

responseStreamWriter.Write(students); to
responseStreamWriter.Write(DateTime.Now);

2 个答案:

答案 0 :(得分:4)

您需要重命名students构造函数中使用的PushStreamContent参数。

例如,来自:

response.Content = new PushStreamContent((students, httpContent, context) =>
{
  OnStreamAvailable(students, httpContent, context);
}, "text/plain");

为:

response.Content = new PushStreamContent((stream, httpContent, context) =>
{
  OnStreamAvailable(stream, httpContent, context);
}, "text/plain");

您无法使用students的原因是因为它已在上一行中声明为变量:

var students = _symboleService.GetAll();

答案 1 :(得分:2)

这里有一些问题会妨碍你的进步。

首先,PushStreamContent构造函数中的Action不能重用变量名“students”。看来你认为你正在传递对Action的引用,但这不是它的工作方式。

你可以试试这个:

response.Content = new PushStreamContent(OnStreamAvailable, "text/plain");

但还有另一个问题。 PushStreamContent构造函数的操作中的流是输出流。

public PushStreamContent(Action<Stream, HttpContent, TransportContext> onStreamAvailable);

您需要从OnStreamAvailable处理程序中写入该流。

由于不清楚_symbolService.GetAll()方法是什么,我只能推测从该方法生成的Byte []应该写入你的动作本身的输出流中。

假设您的学生数据实际上不是流或固有的可流传输,这可能是对PushStreamContent类的误用。