日期:2014-05-20  浏览次数:20683 次

【200分】多线程问题
最多只能给到200分了,如果哪位回答得详细的话,再加分(另贴加分也行)
先说下我的要求吧:我希望写一个函数
void Scan(int count, int start, int end)
通过传入线程数,起始端口,来扫描本机打开的端口
这里有两个问题:
1.线程数不等于要扫描的端口数(通常线程数小于端口数)
也就是线程数不等于任务数
2.同步的问题
如果我不做任何同步的处理,结果就有错,比如本来80端口是打开的,检查出来就可能是84端口
用lock做同步不太会,同步后的确不出错了,但是任务是依次执行,而不是并行执行了,多线程就没有任何意义了
我的代码:
C# code

using System.Net.Sockets;
using System.Threading;


        void Scan(int count, int start, int end)
        {
            int current = start;
            for (int i = 0; i < count; i++)
            {
                //我习惯使用闭包,也可以用带参数的委托,或者字段来共享数据
                Thread th = new Thread(() =>
                    {
                       // lock (this)  //这样同步不对,失去了多线程的意义了
                       // {
                            while (current++ <= end)
                            {
                                try
                                {
                                    TcpClient tc = new TcpClient();
                                    tc.Connect("localhost", current);
                                    //已经在窗体装入时:Control.CheckForIllegalCrossThreadCalls = false;
                                    //如果不设置这个属性,怎么才能把数据显示在列表框呢?
                                    listBox1.Items.Add(current);
                                }
                                catch { }
                            }
                       // }
                    });
                th.IsBackground = true;
                th.Start();
            }
        }

调用:
Scan(10, 1, 255);



------解决方案--------------------
先来抢个沙发,

要知晓正确答案,请看楼下。。。。。。。。。。。。。
------解决方案--------------------
建议把代码贴全~
------解决方案--------------------
C# code

 private void DoWork(object sender, DoWorkEventArgs e)
        {
            //模拟进度条
            for (int i = 0; i < 10; i ++)
            {
                Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
                {
                    WorkProgress.Value = i*10;
                }));
                Thread.Sleep(100);
            }
            try
            {
                if(strUrl!=string.Empty)
                    parseUrl(strUrl);
            }
            catch
            {
                    flvUrl="error";
            }
        }
        private void BeforeWork()
        {
            imageLoad.Visibility = Visibility.Visible;
            WorkProgress.Visibility = Visibility.Visible;
            WorkProgress.Maximum = 100;
            WorkProgress.Minimum = 0;
            WorkProgress.Value = 0;
            btnGet.IsEnabled = false;
            strUrl = textBox1.Text;
        }

        private void FinsihWork(object sender,RunWorkerCompletedEventArgs e)
        {
            WorkProgress.Visibility = Visibility.Hidden;
            imageLoad.Visibility = Visibility.Hidden;
            btnGet.IsEnabled = true;
            if (flvUrl != "error")
                tbResult.Text = flvUrl;
        }

------解决方案--------------------
这么点看不出名堂来
------解决方案--------------------
参考资料C# WinForm开发系列 - Thread/Delegate/Event
------解决方案--------------------
直接这样做事做不到的,TabPage并没有实现IClone接口,无法复制。
我的建议:

你的TabPage1的界面初始化,使用代码来完成,增加一个方法,里面控件的命名要与TabPage1的名称相关联,意在避免命名重复。
TabPage ConstructTabPage()
{
...
}

你如果需要一个tabpage的话,就调用该方法,返回一个,然后将该TabPage添加到TabControl里面就可以了
最好实现预绑定,也就是在构造TabPage的时候,把数据也传进去,如:
TabPage ConstructTabPage(DataTable dt)