كيف يمكنني استخدام WaitHandler.WaitAll في MSTest دون تحذيرات STA؟

StackOverflow https://stackoverflow.com/questions/3246207

سؤال

هل هناك طريقة لاختبار الوحدة WaitHandle.WaitAll() عند استخدام حل اختبار الوحدة المدمج في Visual Studio.عندما أحاول إجراء اختبار يستخدم هذه الوظيفة داخل Visual Studio، يفشل الاختبار وعند فحص نتائج الاختبار يتم عرض الخطأ التالي:

WaitAll for multiple handles on a STA thread is not supported

أود أن أكون قادرًا على اختبار الوحدة لاستخدام WaitAll() نظرًا لأن مقدارًا متزايدًا من قاعدة أكواد واجهة برمجة التطبيقات (API) الخاصة بي ينتقل الآن إلى IAsyncResult النمط بدلاً من الوسائل الأخرى للقيام بعمليات متعددة الخيوط.

يحرر

بناءً على اقتراح أنتوني، إليك طريقة مساعدة بسيطة يمكن استخدامها لاستدعاء مثل هذا الكود في بيئة اختبار الوحدة:

public static void TestInMTAThread(ThreadStart info)
{
    Thread t = new Thread(info);
    t.SetApartmentState(ApartmentState.MTA);
    t.Start();
    t.Join();
}
هل كانت مفيدة؟

المحلول

قد يكون لديك مشكلتين.الأول هو الذي ذكرته:لا يمكنك الانتظار على مقابض انتظار متعددة في موضوع STA (حالة شقة مؤشر الترابط MSTest).يمكننا إصلاح ذلك باستخدام مؤشر ترابط MTA الذي تم إنشاؤه يدويًا.

public static void OnMtaThread(Action action)
{
    var thread = new Thread(new ThreadStart(action));
    thread.SetApartmentState(ApartmentState.MTA);
    thread.Start();
    thread.Join();
}

البيئة لديها أيضا الحد الأقصى لمقبض الانتظار.في .NET 2.0، يبدو أنه تم ترميزه بشكل ثابت إلى 64.الانتظار أكثر من الحد سوف ينتج عنه NotSupportedException.يمكنك استخدام امتداد طريقة الانتظار على كافة مقابض الانتظار في قطع.

public static void WaitAll<T>(this List<T> list, TimeSpan timeout)
    where T : WaitHandle
{
    var position = 0;
    while (position <= list.Count)
    {
        var chunk = list.Skip(position).Take(MaxWaitHandles);
        WaitHandle.WaitAll(chunk.ToArray(), timeout);
        position += MaxWaitHandles;
    }
}

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

OnMtaThread(() => handles.WaitAll(Timespan.FromSeconds(10)));

نصائح أخرى

في فيجوال ستوديو 2008 و 2010 يمكنك تغيير الخاص بك .testsettings ملف لتشغيل الاختبارات ضمن مؤشر ترابط MTA عن طريق إضافة <ExecutionThread apartmentState="MTA" />.

<Execution>
     <ExecutionThread apartmentState="MTA" />
</Execution>

بالنسبة لبرنامج Visual Studio 2010 الخاص بي، فإن التكوين التالي فقط هو الذي جعل الاختبارات تعمل.

<Execution>
     <ExecutionThread apartmentState="1" />
</Execution>

بالنسبة لـ VS2008، تختلف التعليمات قليلاً مقارنة بـ VS2010.بالنسبة لـ VS2008، قم بتحرير ملف testrunconfig، وأضف ما يلي إلى عنصر TestRunConfiguration:

<ExecutionThread apartmentState="MTA" />
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top