سؤال

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

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

public class DirtyWorkaround {
  private class DirtyWriter : TextWriter {
    private TextWriter stdoutWriter;
    private StreamWriter fileWriter;

    public DirtyWriter(string path, TextWriter stdoutWriter) {
      this.stdoutWriter = stdoutWriter;
      this.fileWriter = new StreamWriter(path);
    }

    override public void Write(string s) {
      stdoutWriter.Write(s);

      fileWriter.Write(s);
      fileWriter.Flush();
    }

    // Same as above for WriteLine() and WriteLine(string),
    // plus whatever methods I need to override to inherit
    // from TextWriter (Encoding.Get I guess).
  }

  public static void Main(string[] args) {
    using (DirtyWriter dw = new DirtyWriter("path", Console.Out)) {
      Console.SetOut(dw);

      // Teh codez
    }
  }
}

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

أيضًا، عذرًا على عدم الدقة في الكود أعلاه (كان عليك كتابته مخصصة, ، آسف ؛).

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

المحلول

الحل الأمثل لهذا هو الاستخدام log4net مع مُلحق وحدة التحكم ومُلحق الملف.هناك العديد من الملاحق الأخرى المتاحة أيضًا.كما يسمح لك بإيقاف تشغيل المُلحقات المختلفة وتشغيلها في وقت التشغيل.

نصائح أخرى

لا أعتقد أن هناك أي خطأ في أسلوبك.

إذا كنت تريد تعليمات برمجية قابلة لإعادة الاستخدام، ففكر في تنفيذ فئة تسمى MultiWriter أو شيء من هذا القبيل يأخذ كمدخل اثنين (أو N؟) TextWriter يتدفق ويوزع جميع الأوامر والتدفقات وما إلى ذلك.لتلك التدفقات.بعد ذلك يمكنك القيام بهذا الملف/وحدة التحكم، ولكن بنفس السهولة يمكنك تقسيم أي دفق إخراج.مفيد!

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

أود أن أقول تقليد التشخيص الذي يستخدمه .NET نفسه (التتبع والتصحيح).

قم بإنشاء فئة "إخراج" يمكن أن تحتوي على فئات مختلفة تلتزم بواجهة إخراج النص.تقوم بإبلاغ فئة الإخراج، وتقوم تلقائيًا بإرسال الإخراج المعطى إلى الفئات التي أضفتها (ConsoleOutput، TextFileOutput، مهما كان Output)..وما إلى ذلك وهلم جرا..وهذا أيضًا يتركك مفتوحًا لإضافة أنواع "مخرجات" أخرى (مثل xml/xslt للحصول على تقرير منسق بشكل جيد؟).

تفحص ال تتبع مجموعة المستمعين لنرى ما أعنيه.

فكر في إعادة هيكلة التطبيق الخاص بك لفصل أجزاء تفاعل المستخدم عن منطق الأعمال.من خلال تجربتي، يعتبر هذا الفصل مفيدًا جدًا لبنية برنامجك.

بالنسبة للمشكلة المحددة التي تحاول حلها هنا، يصبح من السهل على جزء تفاعل المستخدم تغيير سلوكه منها Console.WriteLine لملف الإدخال/الإخراج.

أنا أعمل على تنفيذ ميزة مشابهة لالتقاط المخرجات المرسلة إلى وحدة التحكم وحفظها في سجل مع الاستمرار في تمرير المخرجات في الوقت الفعلي إلى وحدة التحكم العادية حتى لا يؤدي ذلك إلى تعطيل التطبيق (على سبيل المثال.إذا كان تطبيق وحدة التحكم!).

إذا كنت لا تزال تحاول القيام بذلك في التعليمات البرمجية الخاصة بك عن طريق حفظ مخرجات وحدة التحكم (بدلاً من استخدام نظام التسجيل لحفظ المعلومات التي تهمك حقًا فقط)، فأعتقد أنه يمكنك تجنب التدفق بعد كل كتابة، طالما كما تقوم أيضًا بتجاوز Flush() والتأكد من أنه يقوم بمسح النسخة الأصلية stdoutWriter قمت بحفظها وكذلك الخاص بك fileWriter.تريد القيام بذلك في حالة محاولة التطبيق مسح خط جزئي إلى وحدة التحكم للعرض الفوري (مثل مطالبة الإدخال، ومؤشر التقدم، وما إلى ذلك)، لتجاوز التخزين المؤقت العادي للخط.

إذا كان هذا الأسلوب يواجه مشكلات في تخزين مخرجات وحدة التحكم الخاصة بك مؤقتًا لفترة طويلة جدًا، فقد تحتاج إلى التأكد من مسح WriteLine() stdoutWriter (ولكن ربما لا تحتاج إلى التنظيف fileWriter إلا عندما يتم استدعاء تجاوز Flush() الخاص بك).ولكن أعتقد أن الأصلي Console.Out (الانتقال فعليًا إلى وحدة التحكم) سيؤدي تلقائيًا إلى مسح المخزن المؤقت الخاص به على سطر جديد، لذلك لا يجب عليك فرضه.

قد ترغب أيضًا في تجاوز Close() إلى (مسح و) إغلاق ملفك fileWriter (وربما stdoutWriter أيضًا)، لكنني لست متأكدًا مما إذا كان ذلك مطلوبًا بالفعل أو إذا كان Close() في TextWriter الأساسي سيصدر Flush() (والذي ستتجاوزه بالفعل) وقد تعتمد على خروج التطبيق لإغلاق ملفك.ربما يجب عليك اختبار أنه يتم مسحه عند الخروج للتأكد.وكن على علم بأن الخروج غير الطبيعي (التعطل) لن يؤدي على الأرجح إلى تدفق الإخراج المخزن مؤقتًا.إذا كانت هذه مشكلة، التنظيف fileWriter على السطر الجديد قد يكون أمرًا مرغوبًا فيه، ولكن هذه علبة أخرى صعبة من الديدان التي يجب حلها.

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