الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

مشكلة التوقف في المشيد حتى اكتمال البيانات

بدأه hfsh80 في 29 أغسطس 2012 · 7 رد · 683 مشاهدة · في Microsoft Visual C#.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

إذا كان لدينا الفئة التالية :

public class WebTest
    {
        private WebBrowser _browser;
        private bool _done;

        public string Data;

        public WebTest()
        {
            _browser = new WebBrowser();
            _browser.DocumentCompleted += _browser_DocumentCompleted;
            _browser.Url=new Uri("http://www.google.com");
            while (!_done)
                Thread.Sleep(50);

            _browser.Dispose();
        }

        void _browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            // هنا يتم الحصول على أي نص من الموقع ويوضع في الحقل Data

            _done = true;
        }
    }

هذا الجزء الأساسي من الفئة والفكرة الأساسية منها جلب نص من موقع معين وتوضع في الحقل Data

عند إنشاء كائن من هذه الفئة فإن البرنامج يتوقف عن الإستجابة والسبب في ذلك أن البرنامج لا يقوم ( كما هو متوقع ) بالدخول للدالة _browser_DocumentCompleted عند اكتمال تحميل الصفحة ويبقى معلقا في حلقة الدوران الموجودة في نهاية المشيد والسبب في ذلك أن _done لن تكون true أبدا ,

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

مالسبب في هذا السلوك ؟ ومالحل ؟

تم تعديل هذه المشاركة بواسطة hfsh80 في 29 أغسطس 2012 في 01:31

#2

نعم أخي لأنهما يتبعان ثريد واحد

لديك حلان

إما حذف حلقة الانتظار مع نقل السطر _browser.Dispose();

إلى داخل حدث DocumentCompleted

وإما باستخدام ملتي ثريد

اطلع على الدروس التالية ستحل المشكلة إن شاء الله

تابع المشاركة السابقة

وبشكل عام القناة التالية رائعة وفيها أشياء مميزة

http://www.youtube.c...o/videos?view=0

تم تعديل هذه المشاركة بواسطة أبو أحمد المبرمج في 29 أغسطس 2012 في 01:53

ما أقبـح المعصية ، تذهب لذتها ويبقى إثمها ... ومأ أحسن الطاعة ، تذهب مشقتها ويبقى ثوابها

كل نعيم دون الجنة غرور ... وكـل شقـاء دون النـار سرور

الدورة التطبيقية لتعليم التصميم بالإليستريتور

#3

شكرا لك أخي الكريم على تفضلك بالرد

الحل الأول لايخدم ما أريد تنفيذه سيتم الانتهاء من المشيد قبل جلب المعلومات .

أي أننا عندما نقوم بإلغاء الحلقة من المشيد ثم نستخدم الفئة بالشكل التالي :

            var test = new WebTest();
            var data = test.Data;

فإننا دائما نحصل على null كقيمة للحقل Data ، والسبب واضح هو أن حدث انتهاء تحميل الصفحة لم ينفذ بعد .

أما فيما يتعلق بالحل الآخر وهو استخدام MultiThreads فالمشكلة واحدة لأننا سنظطر لانتظار الـ Thread المنشئ في المشيد وهو ما يجعل الحل مشابه للحالة الأولى .

وهذا هو المثال لو طبقنا ذلك باستخدام Thread منفصل .

    public class WebTest
    {
        private WebBrowser _browser;
        private bool _done;

        public string Data;

        public WebTest()
        {
            _browser = new WebBrowser();
            _browser.DocumentCompleted += _browser_DocumentCompleted;
            _browser.Url = new Uri("http://www.google.com");

            var task = Task.Factory.StartNew(Waiting);
            task.Wait();
            _browser.Dispose();

        }

        private void Waiting()
        {
            while (!_done)
                Thread.Sleep(50);
        }

        void _browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            // هنا يتم الحصول على أي نص من الموقع ويوضع في الحقل Data
            _done = true;

        }
    }

سيقف البرنامج عند نقطة الانتظار ولن يتم إطلاق حدث إتمام تحميل الصفحة .

شكر ا لك وبانتظار المزيد من الأراء :)

تم تعديل هذه المشاركة بواسطة hfsh80 في 29 أغسطس 2012 في 02:54

#4

بارك الله فيكم ونفع بعلمكم بانتظار المزيد من المعلومات والآراء .

#5

حياك الله أخي

طالما أنك تريد إبقاء المشيد حتى يتم تنفيذ الحدث دوكيومنت كومبليت

إذا فالحل الأول الذي طرحته لك ينفع

أي ألغي حلقة الانتظار حتى يتمكن التنفيذ من الخروج من جسم المشيد لكي يتاح إطلاق الحدث

وعند إطلاق الحدث قم بتدمير الكائن وأكمل طريقك

إذا كان هذا لا ينفع فلو تتكرم بتوضيح المطلوب بالضبط لكي نحاول الوصول لطريقة مثلى للحل.

وبالتوفيق إن شاء الله

ما أقبـح المعصية ، تذهب لذتها ويبقى إثمها ... ومأ أحسن الطاعة ، تذهب مشقتها ويبقى ثوابها

كل نعيم دون الجنة غرور ... وكـل شقـاء دون النـار سرور

الدورة التطبيقية لتعليم التصميم بالإليستريتور

#6

السلام عليكم

جرب هذا الكود

using System.Net;

 class _WebClient : WebClient
    {
        public string Data;

        public _WebClient()
        {
           this.Data = this.DownloadString("http://www.google.com");
        }
    }

_WebClient wc = new _WebClient();
MessageBox.Show(wc.Data);

افترض أنك لا تحتاج بالضرورة WebBrowser في مشروعك, المهم تريد سورس html للصفحة, و لو احتجته, اجعل الكلاس WebTest ترث مباشرة من WebBrowser

تم تعديل هذه المشاركة بواسطة khatibe_30 في 31 أغسطس 2012 في 23:20

[سبحان الله و بحمده, سبحان الله العظيم]

#7

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

ما أقبـح المعصية ، تذهب لذتها ويبقى إثمها ... ومأ أحسن الطاعة ، تذهب مشقتها ويبقى ثوابها

كل نعيم دون الجنة غرور ... وكـل شقـاء دون النـار سرور

الدورة التطبيقية لتعليم التصميم بالإليستريتور

#8

وجدت هذه الآلية أظن أنها تفيد في مثل هكذا حالات

http://msdn.microsof...=VS.110%29.aspx

وهي تقوم على مبدأ التزامن والانتظار

تماما مثل الطلبات من السيرفر

حيث يتم إيقاف التنفيذ في المكان الذي يسبق تعليمة await و يكمل في حال اكتمل تنفيذ المنهج الذي تم التزامن معه

وهذه صورة من الصفحة السابقة توضح ذلك :

IC612215.png

تم تعديل هذه المشاركة بواسطة أبو أحمد المبرمج في 16 سبتمبر 2012 في 14:32

ما أقبـح المعصية ، تذهب لذتها ويبقى إثمها ... ومأ أحسن الطاعة ، تذهب مشقتها ويبقى ثوابها

كل نعيم دون الجنة غرور ... وكـل شقـاء دون النـار سرور

الدورة التطبيقية لتعليم التصميم بالإليستريتور

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…