سؤال

ولدي التطبيق الذي يحتاج إلى حلقة عبر كافة الخطوط في ملفات نصية، على مدى غيغابايت في الحجم. بعض هذه الملفات يكون في 10 أو 100 ملايين من الخطوط.

ومثال على قراءتي الحالية (ومتزامن)، يبدو شيء من هذا القبيل ...

  using (FileStream stream = new FileStream(args[0], FileMode.Open, FileAccess.Read, FileShare.Read)) {
    using (StreamReader streamReader = new StreamReader(stream)) {
      string line;
      while (!string.IsNullOrEmpty(line = streamReader.ReadLine())) {           
        //do stuff with the line string...
      }
    }
  }

ولقد قرأت بعض الاشياء حول أساليب تدفق صافي غير المتزامن IO، وأنا بعد بعض المساعدة مع 2 أسئلة محددة بشأن هذه المسألة.

أولا، سوف أحصل على تعزيز الأداء من خلال قراءة asyncronously هذه الملفات، وإذا كنت بحاجة إلى entireity كل سطر، والتي هي باختصار Ussually ل، ولكن بأطوال مختلفة (ليس هناك علاقة بين كل من الأسطر في الملف)؟

وثانيا، كيف يمكنني تحويل رمز أعلاه، إلى قراءة المتزامن، حتى أتمكن من معالجة كل سطر سطرا، كما أفعل الآن؟

هل كانت مفيدة؟

المحلول

وبدلا من جعل الخط يقرأ التزامن قد حاولت جعل ملف يقرأ التزامن. وهذا هو يشمل كافة التعليمات البرمجية في سؤالك في مندوب عامل واحد.

    static void Main(string[] args)
    {
        WorkerDelegate worker = new WorkerDelegate(Worker);
        // Used for thread and result management.
        List<IAsyncResult> results = new List<IAsyncResult>();
        List<WaitHandle> waitHandles = new List<WaitHandle>();

        foreach (string file in Directory.GetFiles(args[0], "*.txt"))
        {
            // Start a new thread.
            IAsyncResult res = worker.BeginInvoke(file, null, null);
            // Store the IAsyncResult for that thread.
            results.Add(res);
            // Store the wait handle.
            waitHandles.Add(res.AsyncWaitHandle);
        }

        // Wait for all the threads to complete.
        WaitHandle.WaitAll(waitHandles.ToArray(), -1, false); // for < .Net 2.0 SP1 Compatibility

        // Gather all the results.
        foreach (IAsyncResult res in results)
        {
            try
            {
                worker.EndInvoke(res);
                // object result = worker.EndInvoke(res); // For a worker with a result.
            }
            catch (Exception ex)
            {
                // Something happened in the thread.
            }
        }
    }

    delegate void WorkerDelegate(string fileName);
    static void Worker(string fileName)
    {
        // Your code.
        using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            using (StreamReader streamReader = new StreamReader(stream))
            {
                string line;
                while (!string.IsNullOrEmpty(line = streamReader.ReadLine()))
                {
                    //do stuff with the line string...
                }
            }
        }
    }

نصائح أخرى

ونمط المتزامن هو BeginRead () / EndRead ().

وأم لا تحصل على دفعة يعتمد كثيرا على ما يجري في ذلك الوقت كنت تريد ان تفعل يقرأ. هل هناك شيء آخر التطبيق يمكن القيام به في الوقت الذي تنتظر على يقرأ؟ إذا لم يكن ثم سوف المتزامن الذهاب لا يساعد كثيرا ...

وغير المتزامن يقرأ سوف فقط في نهاية المطاف جعل رئيس يسعى أكثر لكل كتلة. سوف تحصل على دفعة أداء أفضل من ديفراغ لا بأس به من الملفات على نظام الملفات واستخدام القراءة متزامن.

وكما سبق أن ذكرنا، وإيفاد تجهيز خط المواضيع الأخرى يجب أن تعطي دفعة (وخاصة على وحدات المعالجة المركزية متعددة النوى)

وإذا كان الأداء فائقة الحرج أوصي التحقيق إمكانية التشغيل المتداخل لFILE_FLAG_SEQUENTIAL_SCAN انظر <لأ href = "http://support.microsoft.com/default.aspx؟scid=kb؛EN-US؛9875" يختلط = "نوفولو noreferrer "> التفاصيل هنا

والأفضل من ذلك إرسال C ++ التطبيق الصغير الذي يمسح من خلال ملف بهذا العلم على لمعرفة ما اذا كان يحسن الأداء.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top