C#网络编程与多线程的疑问,求指点

不才是个菜鸟,第一次接触网络编程,遇到一个TCP编程任务,就是每2秒向一个服务器请求一次数据,然后从服务器返回的数据中提取出需要的,显示在界面上。但是担心出现服务器响应不... 不才是个菜鸟,第一次接触网络编程,遇到一个TCP编程任务,就是每2秒向一个服务器请求一次数据,然后从服务器返回的数据中提取出需要的,显示在界面上。

但是担心出现服务器响应不及时的情况,阻塞住整个程序,这段时间内其他的按钮也不能响应,就太糟糕了,因此想用多线程。可惜多线程之前也没有接触过。
求高人指点两个问题:
(1)如果用多线程的话,应该吧那些东西放入另一个线程中呢?
(2)其他线程可以操纵界面线程中的控件吗?
展开
 我来答
fujie724
2013-09-16 · TA获得超过1187个赞
知道小有建树答主
回答量:154
采纳率:100%
帮助的人:272万
展开全部

1、这种情况下,多线程当然是要把最占用时间的步骤,以及循环的部分,放到线程里。

2、其他线程的代码无法直接操作UI线程里的控件。需要使用委托。


你具体的需求我不是很清楚。但是我在这里假设一个例子:


比如我有个买票的程序,必须每隔2秒,去服务器请求门票的剩余数量。显示在界面上。

界面上还有诸如“售票”“退票”之类的操作。界面如图:

那么代码可以这么写:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        //BackgroundWorker是一个经过良好封装的线程类。.net里自带。
        private BackgroundWorker bg = new BackgroundWorker();
        //委托,用以改变界面显示
        private delegate void delegateSetCounter(int count);

        public Form1()
        {
            InitializeComponent();
            //设定BackgroundWorker要做的事
            bg.DoWork += new DoWorkEventHandler(bg_DoWork);
            //设定BackgroundWorker支持中断线程
            bg.WorkerSupportsCancellation = true;
        }

        //线程要做的事的主体部分
        private void bg_DoWork(object sender, DoWorkEventArgs e)
        {
            //在这里,假设了线程无限循环
            while (true)
            {
                //如果线程被取消就退出
                if (bg.CancellationPending)
                    return;
                //这里用随机数获取,模拟从数据库里取数据
                Random r = new Random(DateTime.Now.Second);
                int count = r.Next(1, 100);
                //委托,关联DoSetCounter函数
                delegateSetCounter sc = new delegateSetCounter(DoSetCounter);
                //将余票传入委托做参数,异步调用
                this.BeginInvoke(sc,count);
                //每次暂停2秒
                Thread.Sleep(2000);
            }
        }

        //委托的部分,简单将传进来的数值显示到界面上的一个Label里
        private void DoSetCounter(int i_count)
        {
            lblCounter.Text = string.Format("余票{0}张", i_count);
        }

        //线程开始运行,如果需要打开程序就开始运行,放到Load事件中就好。
        private void btnStart_Click(object sender, EventArgs e)
        {
            bg.RunWorkerAsync();
        }

        //线程暂停,如果不需要暂停就不用,这里只是说明用法
        private void btnStop_Click(object sender, EventArgs e)
        {
            bg.CancelAsync();
        }

        //窗体关闭时,停止线程
        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);
            bg.CancelAsync();
        }
    }
}


运行之后,点击我们做的那个开关按钮“开始”

Label上就开始每隔2秒显示随机的票数。

而UI线程上的其他控件和操作,都不会被阻塞、卡死。



纯手打写例子。。。谢谢采纳

在忠济寺睡懒觉的黑豹
2013-09-16 · TA获得超过2223个赞
知道小有建树答主
回答量:443
采纳率:0%
帮助的人:265万
展开全部
1、思路应该是,主线程的UI线程或者是主线程本身开启子线程去操作数据。这样能保证线程安全。
2、同样是上面的思路。推荐你用一个委托当作回调,开启线程,请求数据,接到数据后在子线程中调用委托,在委托的实现中操作主线程UI。

如果对多线程不熟悉,尽量不要用Abort方法。线程执行完自己会进入“墓碑”状态,线程池满的时候,会自动清理这些执行完的线程。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
fistlong
2013-09-16 · 超过30用户采纳过TA的回答
知道答主
回答量:69
采纳率:0%
帮助的人:64.4万
展开全部
  1. 你可以用异步去做,或者用多线程的话把数据收发放到线程里就行了

  2. 可以.

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式