【问题标题】:ASP.NET MVC manage objectsASP.NET MVC 管理对象
【发布时间】:2015-03-12 06:37:54
【问题描述】:

NET MVC,现在我有一种情况,在我的控制器中,当单击按钮时,我正在创建一个局部视图,并且视图的模型包含一个侦听事件的类。

StreamModel streamModel = m_StreamModel = new StreamModel(cameraId, rgsLiveVideoWebCall);

string view = RenderRazorViewToString("ImageView", streamModel);

public string RenderRazorViewToString(string viewName, object model)
    {
        ViewData.Model = model;
        using (var sw = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext,
                                                                     viewName);
            var viewContext = new ViewContext(ControllerContext, viewResult.View,
                                         ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);
            viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
            return sw.GetStringBuilder().ToString();
        }
    }

StreamModel 类如下所示:

public class StreamModel
{
    public StreamHolder StreamHolder { get; set; }

    public string Image { get; set; }

    public StreamModel(string cameraId, string url)
    {
        StreamHolder = new StreamHolder(cameraId, url);
    }
}

还有这样的 StreamHolder 持有者类:

public class StreamHolder
{
    private object GetNewImageLock = new object();

    public string CameraId { get; set; }

    private MJPEGStream m_MJPEGStream;

    public byte[] CurrentImageBytes { get; set; }

    public string ImageBase64 { get; set; }


    public StreamHolder(string cameraId, string url)
    {
        CameraId = cameraId;
        CurrentImageBytes = null;
        ImageBase64 = null;
        lock (this)
        {
            m_MJPEGStream = new MJPEGStream(url);
            m_MJPEGStream.RequestTimeout = 100000;
            m_MJPEGStream.ForceBasicAuthentication = true;
            m_MJPEGStream.Login = "admin";
            m_MJPEGStream.Password = "admin";
            m_MJPEGStream.NewFrame += stream_NewFrame;
            m_MJPEGStream.PlayingFinished += stream_PlayingFinished;
            m_MJPEGStream.VideoSourceError += stream_VideoSourceError;
            m_MJPEGStream.Start();
        }
    }

    public void StopStreaming()
    {
        lock (this)
        {
            if (m_MJPEGStream != null)
            {
                try
                {
                    m_MJPEGStream.Stop();
                    m_MJPEGStream.WaitForStop();
                    m_MJPEGStream.NewFrame -= stream_NewFrame;
                    m_MJPEGStream.PlayingFinished -= stream_PlayingFinished;
                    m_MJPEGStream.VideoSourceError -= stream_VideoSourceError;
                    m_MJPEGStream = null;
                }
                catch { }
            }
        }
    }

    private void stream_VideoSourceError(object sender, VideoSourceErrorEventArgs eventArgs)
    {
        StopStreaming();
    }

    private void stream_PlayingFinished(object sender, ReasonToFinishPlaying reason)
    {
        StopStreaming();
    }

    private void stream_NewFrame(object sender, NewFrameEventArgs eventArgs)
    {
        lock (GetNewImageLock)
        {
            if (HomeController.m_LastImageRequest != null && (DateTime.Now - HomeController.m_LastImageRequest).TotalSeconds > 10)
            {
                StopStreaming();
                return;
            }

            if (eventArgs.Frame != null)
            {
                CurrentImageBytes = BitmapToBytes(eventArgs.Frame);
                var base64 = Convert.ToBase64String(CurrentImageBytes);
                ImageBase64 = String.Format("data:image/gif;base64,{0}", base64);
            }
        }
    }

    // This method is for converting bitmap into a byte array
    private static byte[] BitmapToBytes(Bitmap img)
    {
        byte[] byteArray = new byte[0];
        using (MemoryStream stream = new MemoryStream())
        {
            img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
            stream.Close();
            byteArray = stream.ToArray();
        }
        return byteArray;
    }
}

我有两个主要问题: 1) 我可能有超过 1 个此模型的实例,我需要在创建它们后访问和管理它们。 2)当标签/窗口关闭时,我需要正确处理它们。

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-3


    【解决方案1】:

    你可以拥有一个

    private static List<StreamModel> streamModels = new List<StreamModel>();
    

    在你的一门课上。你可以定义一个方法,像这样:

    public static StreamModel generateStreamModel(string cameraid, string url) {
        StreamModel streamModel = new StreamModel(cameraid, url);
        streamModels.Add(streamModel);
        return streamModel;
    }
    

    要释放实例,请将其从 streamModels 中删除。如果未引用,则应由垃圾收集器收集。

    【讨论】:

    • 入口点是控制器操作方法,它链接所有对象,所以当请求得到处理并且控制器实例得到处理时,它不会全部被 GC 收集吗?
    • @JenishRabadiya 已经尝试过使用静态列表的解决方案,我知道它有效的问题是 StreamHolder 对象正在侦听从远程服务器发送的事件,所以即使在处理对象仍在监听事件的控制器,远程服务器不知道何时停止其工作/发送事件
    • @user1531186 静态列表与实例无关,因此它不会随着实例的处置而被处置,但实例成员应该在实例本身被处置时被处置。
    • @JenishRabadiya 我知道,这个想法是每个对象都从打开的流中获取图像,现在我需要关闭流(StopStreaming 方法)以防用户关闭选项卡/窗口,但是我怎么知道发生了(问题的第 2 部分)?
    猜你喜欢
    • 2011-09-26
    • 1970-01-01
    • 2010-09-24
    • 2012-08-24
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 2016-09-15
    • 1970-01-01
    相关资源
    最近更新 更多