繁体   English   中英

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

[英]What is the best way of serializing the tasks using threads in 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; }
    } 

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

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

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

使用BlockingCollection ,您可以让您的线程在队列上进行非繁忙的等待。 同样,当输入线程完成读取时,它可以在队列上调用CompleteAdding以发出信号,表明没有更多的工作项。 当处理线程读取队列时,它可以检查IsCompleted属性以确定是否所有项目都已完成,然后退出。 读取输出队列时,输出线程也是如此。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM