在线程和DataGridViewComboBoxColumn中打开webcontrol

时间:2012-07-28 11:44:50

标签: datagridview webrequest

我希望我的表单应用程序启动多个线程以并行地从站点下载源代码。

这只是主要应用程序的一部分。

链接到图片:http://www.abload.de/img/pic9aym7.png
我不允许发布图片。

    private void buttonstart_Click(object sender, EventArgs e)
    {
         //check the list below
    }

    private void buttonabort_Click(object sender, EventArgs e)
    {
         //should always could abort the process/threads. (close all webcontrols ect)
    }
  1. 它应该开始读取框中的数字。
  2. foreach号码应该打开webbrowser或httpwebrequest来下载一些源代码并计算运行次数(在本例中为4次运行)。
    因此,如果网站像“http://www.bla.com/”,它应该将运行添加到变量的末尾(http://www.bla.com/1-4)。
  3. 将源解析为不同的字符串。 (strWebsiteString1,strWebsiteString2等等。稍后我会需要它们)

  4. 如果这样做,它应该读取一些表(来自字符串)并将它们解析为数组。 (同样在这里array1 [3],array2 [3],以备将来使用)
    为了获得表格,我想我将使用htmlagilitypack。 我已经为控制台编写了这个htmlagilitything。我只需要为我的表单应用程序重建它,并更改控制台writeline以将其放在某些数组中。

    但我对其他/更好的解决方案持开放态度。

  5. 我解析到数组中的所有数据现在都应该显示在datagridcolumns中。 每次运行都会有自己的行。 但是当我尝试将项目添加到组合框中时,我会在每个组合框中出现错误。
  6. 为了使它们按正确的顺序排列并知道它来自哪个浏览器数据,column1将获得运行次数。
  7. 我自己已经尝试过了。 我分别遇到线程交叉线程。 而datagridview也遇到了很多麻烦。

    帮我一个忙,帮我解决这个问题,并告诉我可能会显示一个可以帮助我的片段/样本。

1 个答案:

答案 0 :(得分:0)

这是一个明显的例子,展示了我在上述评论中所说的内容。它使用锁而不是Mutex,但你会明白这一点。这是一个简单的代码,使用多线程Job生成器向同一个(锁定的)资源添加信息,一个消费者每秒运行一次以与表单控件-ListBox交互 - 在这种情况下 - 清除作业缓存。

您可以在此处找到更多信息http://www.albahari.com/threading/part2.aspx

public partial class Form1 : Form
{
    static readonly Queue<Job> queue = new Queue<Job>();

    public Form1()
    {
        InitializeComponent();
        //starts the timer to run the ProcessJobs() method every second
        System.Threading.Timer t = new System.Threading.Timer(obj => { ProcessJobs(); }, null, 5000, 1000);                
    }               

    /// <summary>
    /// Called by informations producers to add jobs to the common queue
    /// </summary>        
    private void AddJob(Job job)
    {
        lock (queue)
        {
            queue.Enqueue(job);
        }
    }

    /// <summary>
    /// Common queue processing by the consumer
    /// </summary>
    private void ProcessJobs() {            
        Job[] jobs;
        lock (queue)
        {
            jobs = queue.ToArray();
            queue.Clear();
        }
        foreach(Job job in jobs){       
            this.Invoke(new Action(delegate {
                listBox1.Items.Add(job.Name);
            }));
        }
    }

    /// <summary>
    /// Producer
    /// </summary>        
    private void JobsProducer(string name) {
        for (int i = 0; i < 10; i++)
        {
            Random r = new Random();
            System.Threading.Thread.Sleep(r.Next(1,10)*50);
            this.AddJob(new Job(string.Format("Job({0}) n.{1}", name, i)));
        }
    }

    /// <summary>
    /// Starts the jobs producers
    /// </summary>        
    private void button1_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < 10; i++)
        {
            string producerName = string.Format("Producer{0}", i);
            new System.Threading.Timer(obj => { JobsProducer(producerName); }, null, 0, System.Threading.Timeout.Infinite);
        }
    }       
}

public class Job
{
    //whatever -informations you need to exchange between producer and consumer
    private string name;
    public string Name { get { return name; } }
    public Job(string name) {
        this.name = name;
    }
}  

在这里,您可以找到一个使用Dictionary来保存多个作业结果的示例:

Dictionary<string, string[]> jobs = new Dictionary<string, string[]>();
//adds an array to the dictionary
//NB: (array it's not well suited if you don't know the values or the size in advance...you should use a List<string>)
jobs.Add("jobNumber1", new string[]{"a","b"});
//gets an array from the dictionary
string[] jobNumber1;
if (!jobs.TryGetValue("jobNumber1", out jobNumber1))
     throw new ApplicationException("Couldn't find the specified job in the dictionary");