توقف WCF عن الاستجابة بعد حوالي 10 مكالمات أو نحو ذلك (اختناق)

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

سؤال

لدي خدمة WCF وتطبيق مع مرجع الخدمة عليه، ومع التطبيق لدي حلقة وفي كل تكرار، فإنه يقوم بإجراء مكالمة إلى طريقة في خدمة WCF هذه.

المشكلة هي أنه بعد حوالي 9 مكالمات أو نحو ذلك، فإنه يتوقف فقط ... وإذا كنت تضغط Pause زر VS، سترى أنه عالق على الخط حيث يجعل المكالمة.

بعد بعض الوقت في انتظار ذلك، هذا timeoutException. هذا خطئ:

انتهت مهلة قناة الطلب أثناء انتظار الرد بعد 00: 00: 59.9970000. قم بزيادة قيمة المهلة التي تم تمريرها إلى الدعوة لطلب أو زيادة قيمة SendTimeOut على الربط. قد يكون الوقت المخصص لهذه العملية جزءا من مهلة أطول.


لقد بحثت قليلا في هذا، ووجدت بعض الحلول التي تنطوي على تحرير App.config في التطبيق، وهنا مقتطفات منه:

<serviceBehaviors>
    <behavior name="ThrottlingIssue">
        <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" />
    </behavior>
</serviceBehaviors>

.

<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" 
 maxArrayLength="2147483647" 
 maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 

بعد ذلك، بعد أن أتوقف عن تصحيح الأخطاء، بعد بضع دقائق، تنطبق رسالة خطأ أخبرني بذلك فشل ذريع قد حدث.

كيف يمكنني حل هذه المشكلة؟ لم يكن لدي هذه المشكلة عندما كنت أعمل مع خدمة ويب عادية.


للرجوع اليها، هنا هو كله app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="ThrottlingIssue">
                    <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IDBInteractionGateway" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                        maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" establishSecurityContext="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:28918/DBInteractionGateway.svc"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDBInteractionGateway"
                contract="DBInteraction.IDBInteractionGateway" name="WSHttpBinding_IDBInteractionGateway">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

تحديث] الحل:

فيما يبدو، بعد كل طلب عليك Close الاتصال... أنا الآن أغلق الاتصال بعد كل طلب ويعمل مثل سحر.

على الرغم من ما ما زلت لا أزال غير قادر على فهمه هو أنه في تطبيق My.config، أقوم بتعيين MaxConcurrentCalls و MaxConcurrantessions إلى 500، ومع ذلك، لا يمكنني تقديم 10. أي شخص لديه أي إجابة لهذا واحد؟ (ربما لدي شيء خاطئ في App.config نشر أعلاه)

الجواب عن السؤال أعلاه (متقطع الآن) هو أنني كنت تحرير العميل app.config, ، وليس ملف تكوين الخدمة (web.config)

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

المحلول

الرقم الافتراضي للاتصالات المتزامنة المسموح بها هو 10.
على الأرجح عميلك لا يغلق الاتصالات.

لزيادة عدد المكالمات المتزامنة، سيتعين عليك إضافة سلوكك إلى تكوين الخدمة وليس العميل.

نصائح أخرى

دعوة إلى clientservice.close () سوف تحل المشكلة.

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

ما قد يكون من المثير للاهتمام أن نلاحظ ما جعلني يقرر أن هذا كان ليس المشكلة: هذا الحد غير مرتبط بالعدد الفعلي من اتصالات المقبس إلى WebService. عندما تضغط maxConcurrentSessions الحد، لا يزال هناك فقط اتصال مأخذ واحد الفعلي. وبعد كنت أتحقق من هذا مع netstat, ، الذي أحضرني إلى الاستنتاج الخطأ. وبالتالي، لا تخلط بين الدورات مع مآخذ.

لدينا واجهات محددة لجميع خدمات WCF لدينا، لذلك أخطط لتكييف هذا النمط في الرمز الخاص بي الآن:

IMyService service = new MyServiceClient();
using (service as IDisposable)
{
    service.MyServiceMethod();
}

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

@ جون سوندرز (حول مهمة متغيرة في using):

عادة ما أفعل المهمة المتغيرة في using بيان. لكن IMYSERVIRE الذي تم إنشاؤه ليس قابل للتحويل ضمنيا ل IDisposable. وبعد إذا كنت تريد حقا المهمة هناك، ففرض البديل سيكون:

IService service;
using ((service = new ServiceClient()) as IDisposable)
{
}

لا يزال يترك مشكلة النطاق المتغير خطأ. الإشارة إلى IService service غير قابل للاستخدام، ولكن لا يزال في نطاق. لذلك سيكون هذا أفضل في هذا الصدد:

using (IDisposable serviceDisposable = new ServiceClient())
{
     IService service = (IService)serviceDisposable;
}

وهذا يتطلب مني أن أقدم اسم متغير إضافي رغم ذلك. *مه*

يمكن حل هذا عن طريق إنشاء فئة Singleton كواجهة بين مرجع وخدمة الويب والتطبيق. ثم سينشئ مثيل واحد فقط من مرجع الخدمة.

class ServiceInterface
{
     private static ServiceInterface  _instance;
     private ServiceClient _service = new ServiceClient ;
     private ServiceInterface()
     {
       //Prevent accessing default constructor
     }

     public static ServiceInterface GetInstance()
     {

     if(_instance == null)

     {

      _instance = new ServiceInterface();

    }

        return _instance;



 }


   // You can add your functions to access web service here

    Public int PerformTask()
    {
         return _service.PerformTask();
    }
}

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

بعد سحب شعري على كثير مشكلة مماثلة لم يتم حلها من قبل Close() أو Dispose() أود إضافة حل بسيط جعل يومي، أي بزيادة ServicePointManager.DefaultConnectionLimit وهو افتراضيا 2.

"تقوم خاصية DefaultConnectionLimit بتعيين الحد الأقصى الافتراضي للأقصى الافتراضي للاتصالات المتزامنة التي يقوم بها كائن ServicePointMointMoager إلى خاصية ConnicoyLimit عند إنشاء كائنات ServicePoint."

في حالتي المتصلة بنجاح إلى الخدمة البعيدة الخاصة بي 2 مرات، في المحاولة الثالثة، لم أحاول ببساطة الاتصال بالخدمة. بدلا من ذلك انتظر بعض الوقت قبل التوقيت مع نفس رسالة الخطأ كما هو الحال في السؤال أعلاه. في ازدياد DefaultConnectionLimit حل هذا. لإضافته إلى الإحباط، كان هذا السلوك عشوائيا إلى حد ما - في حالة واحدة من 10 تم استدعاء Webservice بنجاح (> 2) مرات.

ينشأ الحل وناقشت كذلك هذين المواضيعتين: WCF- مهلة الاستثناء - التحقيق التفصيلي و WCF-Service-Struttling. وبعد حل مشكلتي.

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