在C#.Net Compact Framework中使用线程序列化任务的最佳方法是什么?

时间:2012-11-15 14:10:33

标签: c# .net compact-framework

在我的程序中,我收到一些数据,我必须将其保存到一个文件(一个或多个),数据顺序非常重要,所以它应该像先到先保存一样。

最后,我得到一个信号,表示此时不再有数据可用,我必须关闭所有打开的文件,我该如何处理它,我的意思是我怎样才能确保所有线程都完成了他们的工作所以,我可以关闭文件。

我正在使用ManualResetEvent来控制数据的顺序,以便下一个帖子等待上一个线程完成它的工作。

以下是我的代码示例,我需要指南以非常有效的方式完成同样的工作,我怎么知道所有线程都完成了他们的工作。

class Program
    {
        static StreamWriter _fileStream;
        static void Main(string[] args)
        {
            _fileStream = File.CreateText(@"D:\HelloThread.txt");               
            ManualResetEvent currentEvent = new ManualResetEvent(true);
            ManualResetEvent nextEvent = new ManualResetEvent(false);              
            int length = 60;
            Data data = null;
            Console.WriteLine("Writing started...");
            for (int i = 0; i < length; i++)
            {
                data = new Data { CurrentEvent = currentEvent, Number = i, NextEvent = nextEvent };
                ThreadPool.QueueUserWorkItem(PrintMsg, data);                   
                currentEvent = nextEvent;
                nextEvent = new ManualResetEvent(false);
            }


            Console.ReadLine();
        }

        private static void CloseAll()
        {
            Console.WriteLine("Requested to close all...");


            Console.WriteLine("Done with the writing...");
        }

        private static object _lockObj = new object();

        private static void PrintMsg(object state)
        {
            Data data = state as Data;

            data.CurrentEvent.WaitOne();

            string msg = "Hello times...";
            for (int j = 0; j < 5; j++)
            {
                _fileStream.WriteLine(msg + data.Number);
               // Console.WriteLine(msg + data.Number);
            }

            data.NextEvent.Set();
        }
    }

    public class Data
    {
        public ManualResetEvent CurrentEvent { get; set; }
        public ManualResetEvent NextEvent { get; set; }
        public int Number { get; set; }
    } 

1 个答案:

答案 0 :(得分:3)

听起来您正在描述一个应用程序管道,其中有多个线程,每个线程都在一个工作项的单独部分上工作。例如,一个线程可能正在进行输入,一个线程正在执行进程,一个线程正在执行输出。

通常,您可以通过创建多个队列来处理此问题。假设你有这三个主题。输入线程读取记录并将其放入输入队列。处理线程读取输入队列,处理项目,并将结果放入输出队列。然后输出线程读取输出队列并将数据写入需要的位置。

这确保以正确的顺序处理和编写工作项,但允许所有线程同时工作。

使用BlockingCollection,您可以让线程在队列中执行非忙等待。此外,当输入线程完成读取时,它可以调用队列上的CompleteAdding以表示没有更多工作项。当处理线程读取队列时,它可以检查IsCompleted属性以确定是否所有项都已完成,从而退出。读取输出队列时输出线程也是一样。

有关使用BlockingCollection的一些简单示例,请参阅http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=821

如果你不能使用BlockingCollection,那么你必须在Queue<T>周围包装一个并发层。