C#并行线程但相互控制

时间:2014-10-26 16:08:51

标签: c# multithreading

我想编写一个有2个线程的程序。一个将下载另一个将解析下载的文件。棘手的部分是我不能同时使用2个解析线程,因为它使用库技术来解析文件。请帮忙提出建议。谢谢。

Foreach(string filename in filenames)
{
    //start downloading thread here;
    readytoparse.Add(filename);
}

Foreach(string filename in readytoparse)
{
    //start parsing here
}

我最终得到了以下逻辑

bool parserrunning = false;
List<string> readytoparse = new List<string>();
List<string> filenames= new List<string>();

//downloading method
Foreach(string filename in filenames)
{
    //start downloading thread here;
    readytoparse.Add(filename);
    if(parserrunning == false;
    {
        // start parser method
    }
}

//parsing method
parserrunning = true;
list<string> _readytoparse = new List<string>(readytoparse);
Foreach(string filename in _readytoparse)
{  

    //start parsing here
}
parserrunning = false;

2 个答案:

答案 0 :(得分:0)

优素福,你的问题&#34;很模糊。您可以采用主线程下载文件的方法,然后每次文件完成下载时,生成一个工作线程来解析该文件。对于这种事情,有Task API或QueueUserWorkItem。我认为你可能最终会以这种方式同时运行大量的工作线程,这不一定是更快地完成工作的关键,并且可能会对计算机上的其他并发工作产生负面影响

如果要将此限制为两个线程,则可以考虑让下载线程在每次下载完成时将文件名写入队列。然后你的解析器线程监视该队列(每隔x秒唤醒一次,检查队列以查看是否有任何事情要做,做好工作,再次检查队列,如果没有任何事情要做,请返回睡了x秒,重复一次。

如果您希望解析器具有弹性,请使该队列保持持久性(数据库,MSMQ,磁盘上正在运行的文本文件 - 某些持久性)。这样,如果出现中断(计算机崩溃,程序崩溃,断电),解析器就可以从它停止的地方开始重新启动。

代码同步开始发挥作用,你显然不能让解析器试图解析下载器仍在下载的文件,如果你有两个线程使用队列,那么你显然必须保护该队列不会并发访问。

无论您使用监视器还是互斥锁,QueueUserWorkItem或Task API都是学术性的。 .NET框架中提供了大量支持,用于同步和并行化工作单元。

答案 1 :(得分:0)

我建议尽量避免因使用任何灵长类动物做这件事而感到心痛,并使用专为这类事物设计的图书馆。

我推荐微软的Reactive Framework(Rx)。

以下是代码:

var query =
    from filename in filenames.ToObservable(Scheduler.Default)
    from file in Observable.Start(() => /* read file */, Scheduler.Default)
    from parsed in Observable.Start(() => /* parse file */, Scheduler.Default)
    select new
    {
        filename,
        parsed,
    };

query.Subscribe(fp =>
{
    /* Do something with finished file */
});

很简单。

如果您的解析库只是单线程,那么添加以下行:

var els = new EventLoopScheduler();

然后在解析行上用Scheduler.Default替换els