كيف يمكنني التقاط FileNotfoundException عند الركض على Mono و DLL مفقود؟
-
29-09-2019 - |
سؤال
لدي سطح مكتب Windows 7 X64 مع VS2010 وتثبيت مربع افتراضي من Linux مع Mono و Monodevelop. أقوم بتجميع البرنامج التالي مع VS2010 وقم بتشغيله في جهاز Linux الظاهري ويفشل مع filenotfoundexceptive غير قابل للحياة على ما يبدو. إذا قمت بتجميعه في الجهاز الظاهري وقمت بتشغيله في Windows ، فهو يعمل بشكل رائع.
يبدو أن المشكلة هي أن الاستثناء غير القابل للاضطراب يتم إلقاؤه بواسطة Mono قبل Main () عندما يكون من المستحيل تحميل DLL. هل هناك طريقة لإعادة هيكلة برنامجي أو إجباره على أحادي بحيث يمكنني التقاط هذا الاستثناء؟
أحاول كتابة برنامج واحد يحتوي على واجهة في WPF أو GTK وفقًا لما هو متاح في وقت التشغيل.
using System;
#if __MonoCS__
using Gtk;
#else
using System.Windows;
#endif
using System.IO;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
namespace Test {
public static class Program {
[STAThread]
public static void Main() {
try {
Main2();
} catch (FileNotFoundException e) {
Console.WriteLine("Caught FileNotFoundException");
Console.WriteLine("FileName = {0}", e.FileName);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Main2() {
#if __MonoCS__
Application.Init();
#else
Window w = new Window();
#endif
}
}
}
المحلول
أنت تعرض نفسك لتفاصيل تنفيذ JIT-Compiler. يعتمد الوقت المحدد الذي ستلقي فيه الاستثناء للتجميع المفقود على مدى ترجمة IL إلى رمز الجهاز. أعلم أن Microsoft Jitter حقًا في الوقت المناسب ، فهو يجمع طريقة واحدة في كل مرة ، قبل أن يكون على وشك التنفيذ. على الرغم من أن هذا يتأثر بما إذا كان تصحيح الأخطاء مرفقًا أم لا. أنت ميت في الماء إذا كان Mono ، على سبيل المثال ، يجمع الفصل بأكمله. سوف الرفوف رمي قبل أن يبدأ Main ().
ربما ستعمل بشكل أفضل إذا وضعت Main2 () في فصل آخر. أفضل ما يجب فعله هو أن يكون هناك مجموعة متوفرة ، وهمية إذا لزم الأمر.
نصائح أخرى
ما هو DLL لم يتم العثور عليه؟ أفترض ، انطلاقًا من رمزك ، ربما يكون ذلك. أنا لست على دراية تمامًا بالمعالجة المسبقة C# ، لكنني أعتقد #if __MonoCS__
قد يكون أكثر فائدة (أو قد يتصرف فقط) كما يحدد المعالج المسبق ، أي أنه لا يتغير في وقت التشغيل. قد تحاول التعريف __MonoCS__
بالنسبة للبناء الأحادي في إعدادات المشروع وقم بتشغيل ذلك (أعتقد أنه لا يحدد ذلك بشكل افتراضي ، لذلك ربما يحاول العمل مع WinForms على أي حال).
شيء آخر لمحاولة التعليق using System.Windows
وجميع التعليمات البرمجية ذات الصلة (فقط باستخدام مسار GTK/Mono) واختبار ما إذا كان ذلك يعتمد على Windows ويعمل على كليهما. إذا كان الأمر كذلك ، فقد ضاقت المشكلات المحتملة حتى تتضمن ذلك ، ويجب أن يكون من الأسهل حلها من هناك.
بدلاً من الاعتماد على كسل تحميل التجميع المشار إليه ، أقترح عليك تنفيذ واجهة المستخدم الرسومية الخاصة الخاصة بك في مجموعات مختلفة ، وربما تنفيذ واجهة مشتركة. لن يكون للتجميع الرئيسي بعد ذلك أي إشارات مباشرة إلى مجموعات أدوات واجهة المستخدم الرسومية محددة ، ولكنها ستستخدم الانعكاس لمحاولة تحميل WPF أو GTK من GAC ، واستنادًا إلى ذلك من شأنه أن يستخدم انعكاسًا لتحميل مجموعة DLL محددة ومحددة .
شيء مثل:
- programName.exe - يحتوي
Main
نقطة الدخول،IPlatformGui
, والمنطق المشترك من قبل جميع المنصات - ProgramName.gtk.dll - يحتوي على
GtkGui : IPlatformGui
- ProgramName.wpf.dll - يحتوي على
WpfGui : IPlatformGui