首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

C# 关于线程和I/O流的有关问题

2013-09-24 
C#关于线程和I/O流的问题本帖最后由 u011919488 于 2013-09-11 14:31:57 编辑用一个窗体(以下称A窗体)中的

C# 关于线程和I/O流的问题
本帖最后由 u011919488 于 2013-09-11 14:31:57 编辑 用一个窗体(以下称A窗体)中的线程检测第三方设备的数据 有数据则打开另一个窗体(B窗体,只打开一个)   

B窗体中  有一个System.Threading.Timer 用来监听(HttpListenerContext)数据流 
同时还有一个timer控件 控制窗体抖动    我在关闭这个窗体的时候   会报 “由于线程退出或应用程序请求,已中止 I/O 操作”(如果不使用监听数据流线程则没问题)  
 
代码如下:



 //监听按键信息
        System.Threading.Timer threadTimer;
/// <summary>
        /// 开启监听
        /// </summary>
        private void StartListen()
        {
            threadTimer = new System.Threading.Timer(new TimerCallback(CatchTelNumber), null, 1000, 500);
            listerner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;//指定身份验证 Anonymous匿名访问
            listerner.Prefixes.Add("http://localhost:4529/login/");
            listerner.Start();
        }


  /// <summary>
        /// 获取按键信息
        /// </summary>
        /// <param name="state"></param>
        private void CatchTelNumber(object state)
        {
            _th = new Thread(new ThreadStart(() =>
            {
                //等待请求连接
                //没有请求则GetContext处于阻塞状态
                lock (_lock)
                {
                    HttpListenerContext ctx = listerner.GetContext();


                    ctx.Response.StatusCode = 200;//设置返回给客服端http状态代码
                    string name = ctx.Request.QueryString["c_meb_no"];
                    if (name != null)
                    {
                        catchKey.Append(name);
                        SetBtnEnable(name);
                        using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream))
                        {
                            writer.WriteLine("<html><head><title>WebServer</title></head><body>");
                            writer.WriteLine("<div>hello{0}</div>", name);
                            writer.WriteLine("</body></html>");
                            writer.Close();
                            ctx.Response.Close();
                        }
                    }
                }
            }));
            _th.IsBackground = true;


            _th.Start();
        }



    /// <summary>
        /// 关闭窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox1_Click(object sender, EventArgs e)
        {
            Cl = null;
            Ph = null;
            threadTimer.Dispose();
            listerner.Stop();
            this.Dispose();
        }
i/o 线程
[解决办法]
CatchTelNumber 里面的方法不用线程看看呢?

里面的线程是多余的.
[解决办法]
 threadTimer.Dispose();
            listerner.Stop();

这两句顺序换一下看看.
[解决办法]
这段代码的逻辑有问题,为什么要开那么多线程?
你现在每半秒开一个线程,除了第一线程可以进入lock以外,其它线程都在lock处等待。
第一线程将在listerner.GetContext()处等待,直到出现满足条件的http请求。
这时候第一线程可以顺利执行完毕,第二线程进入lock,在listerner.GetContext()处等待,其它线程继续在lock处等待。
如果这时候 listerner.Stop(),则第二线程(监听listener的线程)异常退出(由于应用程序请求)。第三线程进入lock,在调用listerner.GetContext()的时候,产生异常InvalidOperationException:请在调用此方法前调用 Start() 方法,然后第四第五线程重复这个过程,直到所有线程都异常退出。

热点排行