مشاركة عبر


الإرشادات التفصيلية: تأليف مكوّن بسيط متعدد مؤشرات الترابط باستخدام# Visual C

يستبدل ويضيف مكوّن BackgroundWorker وظائف إلى مساحة أسم System.Threading; ومع ذلك، يتم الإحتفاظ بمساحة أسم System.Threading للتوافق مع الإصدارات السابقة واستخدامها في المستقبل، إذا أردت القيام بذلك. لمزيد من المعلومات، راجع نظرة عامة حول مكوّن BackgroundWorker.

يمكنك كتابة التطبيقات التي بإمكان إلى إنجاز عدة مهام في نفس الوقت. Th هو القدرة على استدعاء متعدد العملياتأو الحرة ترابط ، هو طريقة فعالة لتصميم المكونات غير المعالج بشكل كبير، وتتطلب إدخال مستخدم. مثال مكوّن التي قد تجعل استخدام من متعدد العمليات ستكون مكوّن الذي يقوم بحساب معلومات الرواتب. أن مكوّن بمعالجة البيانات التي تم إدخالها في قاعدة بيانات بواسطة مستخدم تشغيل مؤشر ترابط واحد بينما تم تنفيذ الحسابات الرواتب المعالج بشكل كبير تشغيل آخر. بهذه معالجات قيد التشغيل تشغيل مؤشرات ترابط منفصلة، لا يحتاج المستخدمون إلى انتظار الكمبيوتر إلى إتمام عمليات حسابية قبل إدخال بيانات إضافى. في this معاينة, you will إنشاء a simple multithreaded مكوّن that performs several complex calculations simultaneously.

إنشاء المشروع

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

ملاحظة

Although a دالة هو usually preferable for a أسلوب that calculates a القيمة, الوسيطات cannot be passed between عمليات جزئية, nor can قيم be returned. هناك العديد من الطرق البسيطة إلى توفير قيم إلى مؤشرات الترابط و إلى تلقي قيم منه. سيعود في هذا العرض التوضيحي، قيم الخاصة بك واجهة مستخدم بجاري الآن التحديث المتغيرات العمومية وأحداث سيستخدم لإعلام البرنامج الأساسي عند اكتمال مؤشر ترابط التنفيذ.

قد تختلف مربعات الحوار وأوامر القائمة التى تشاهدها الان عن تلك الموصوفة في التعليمات اعتماداً على الإعدادات النشطة أو الإصدار الخاص بك. لتغيير الإعدادات الخاصة بك, اختر إعدادات الاستيراد و التصدير ضمن القائمة أدوات . لمزيد من المعلومات، راجع العمل مع إعدادات.

إلى إنشاء النموذج

  1. إنشاء جديد مشروع تطبيق Windows.

  2. قم بتسمية تطبيق Calculationsوإعادة تسمية Form1.csكـ frmCalculations.cs. When Visual Studio prompts you إلى إعادة تسمية the Form1 تعليمات برمجية عنصر, انقر نعم.

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

  3. إضافة الخمسة Labelعناصر التحكم، أربع Buttonواحد وعناصر التحكم، TextBoxعنصر التحكم على النموذج الخاص بك.

  4. التعيين خصائص for these عناصر التحكم كـ follows:

    عنصر التحكم

    الاسم

    Text

    label1

    lblFactorial1

    (blank)

    label2

    lblFactorial2

    (blank)

    label3

    lblAddTwo

    (blank)

    label4

    lblRunLoops

    (blank)

    label5

    lblTotalCalculations

    (blank)

    button1

    btnFactorial1

    مضروب

    button2

    btnFactorial2

    مضروب-1

    button3

    btnAddTwo

    إضافة الثاني

    button4

    btnRunLoops

    قم بتشغيل تنفيذ تكرار حلقي مستمرة

    textBox1

    txtValue

    (blank)

إلى إنشاء مكوّن آلة حاسبة

  1. من قائمة مشروع ، تحديد إضافة مكوّن .

  2. اسم the مكوّن Calculator.

إلى إضافة متغيرات عمومية إلى مكوّن Calculaإلىr

  1. محرر تعليمات برمجية بفتح Calculator.

  2. إضافة عبارات لإنشاء المتغيرات العمومية التي سيتم استخدامها لتمرير المعلومات من frmCalculationsلكل مؤشر ترابط.

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

    public int varAddTwo; 
    public int varFact1;
    public int varFact2;
    public int varLoopValue;
    public double varTotalCalculations = 0;
    

إلى إضافة وظائف وأحداث إلى مكوّن Calculaإلىr

  1. Declare the المفوضون for the أحداث that your مكوّن will استخدم إلى communicate قيم إلى your نموذج.

    ملاحظة

    Although you will be declaring الرابع أحداث, you فقط need إلى إنشاء three المفوضون, because الثاني أحداث will have the same توقيع.

    مباشرة أسفل تصريحات متغير التي تم إدخالها في الخطوة السابقة، اكتب ما يلي تعليمات برمجية:

    // This delegate will be invoked with two of your events.
    public delegate void FactorialCompleteHandler(double Factorial, double TotalCalculations);
    public delegate void AddTwoCompleteHandler(int Result, double TotalCalculations);
    public delegate void LoopCompleteHandler(double TotalCalculations, int Counter);
    
  2. Declare the أحداث that your مكوّن will استخدم إلى communicate مع your تطبيق. Do this بواسطة إضافة the following تعليمات برمجية immediately beneath the تعليمات برمجية entered في the السابق step.

    public event FactorialCompleteHandler FactorialComplete;
    public event FactorialCompleteHandler FactorialMinusOneComplete;
    public event AddTwoCompleteHandler AddTwoComplete;
    public event LoopCompleteHandler LoopComplete;
    
  3. Immediately beneath the تعليمات برمجية you typed في the السابق step, نوع the following تعليمات برمجية:

    // This method will calculate the value of a number minus 1 factorial
    // (varFact2-1!).
    public void FactorialMinusOne()
    {
       double varTotalAsOfNow = 0;
       double varResult = 1;
       // Performs a factorial calculation on varFact2 - 1.
       for (int varX = 1; varX <= varFact2 - 1; varX++)
       {
          varResult *= varX;
          // Increments varTotalCalculations and keeps track of the current 
          // total as of this instant.
          varTotalCalculations += 1;
          varTotalAsOfNow = varTotalCalculations;
       }
       // Signals that the method has completed, and communicates the 
       // result and a value of total calculations performed up to this 
       // point.
       FactorialMinusOneComplete(varResult, varTotalAsOfNow);
    }
    
    // This method will calculate the value of a number factorial.
    // (varFact1!)
    public void Factorial()
    {
       double varResult = 1;
       double varTotalAsOfNow = 0;
       for (int varX = 1; varX <= varFact1; varX++)
       {
          varResult *= varX;
          varTotalCalculations += 1;
          varTotalAsOfNow = varTotalCalculations;
       }
       FactorialComplete(varResult, varTotalAsOfNow);
    }
    
    // This method will add two to a number (varAddTwo+2).
    public void AddTwo()
    {
       double varTotalAsOfNow = 0;  
       int varResult = varAddTwo + 2;
       varTotalCalculations += 1;
       varTotalAsOfNow = varTotalCalculations;
       AddTwoComplete(varResult, varTotalAsOfNow);
    }
    
    // This method will run a loop with a nested loop varLoopValue times.
    public void RunALoop()
    {
       int varX;
       double varTotalAsOfNow = 0;
       for (varX = 1; varX <= varLoopValue; varX++)
       {
        // This nested loop is added solely for the purpose of slowing down
        // the program and creating a processor-intensive application.
          for (int varY = 1; varY <= 500; varY++)
          {
             varTotalCalculations += 1;
             varTotalAsOfNow = varTotalCalculations;
          }
       }
       LoopComplete(varTotalAsOfNow, varLoopValue);
    }
    

نقل إدخالات مستخدم مكوّن

الخطوة التالية هو لإضافة تعليمة برمجية إلى frmCalculationsاستلام إدخال من مستخدم بالإضافة إلى نقل وتلقى القيم إلى ومن Calculatorمكوّن.

إلى تنفيذ وظيفية أمامي إلى frmCalculations

  1. فتح frmCalculations في the تعليمات برمجية محرر.

  2. بحث the public partial class frmCalculations كشف. Immediately beneath the { نوع:

    Calculator Calculator1;
    
  3. بحث the الدالة الإنشائية. Immediately قبل the }, إضافة the following خط:

    // Creates a new instance of Calculator.
    Calculator1 = new Calculator();
    
  4. في the مصمم, انقر each زر إلى توليد the تعليمات برمجية مخطط تفصيلي for each عنصر تحكم's Click حدث handlers و إضافة تعليمات برمجية إلى إنشاء the handlers.

    When إكمال, your Click حدث handlers should resemble the following:

    // Passes the value typed in the txtValue to Calculator.varFact1.
    private void btnFactorial1_Click(object sender, System.EventArgs e)
    {
       Calculator1.varFact1 = int.Parse(txtValue.Text);
       // Disables the btnFactorial1 until this calculation is complete.
       btnFactorial1.Enabled = false;
       Calculator1.Factorial();
    }
    
    private void btnFactorial2_Click(object sender, System.EventArgs e)
    {
       Calculator1.varFact2 = int.Parse(txtValue.Text);
       btnFactorial2.Enabled = false;
       Calculator1.FactorialMinusOne();
    }
    private void btnAddTwo_Click(object sender, System.EventArgs e)
    {
       Calculator1.varAddTwo = int.Parse(txtValue.Text);
       btnAddTwo.Enabled = false;
       Calculator1.AddTwo();
    }
    private void btnRunLoops_Click(object sender, System.EventArgs e)
    {
       Calculator1.varLoopValue = int.Parse(txtValue.Text);
       btnRunLoops.Enabled = false;
       // Lets the user know that a loop is running
       lblRunLoops.Text = "Looping";
       Calculator1.RunALoop();
    }
    
  5. بعد the تعليمات برمجية you تمت الإضافة في the السابق step, نوع the following إلى مؤشر the أحداث your نموذج will receive من Calculator1:

    private void FactorialHandler(double Value, double Calculations)
    // Displays the returned value in the appropriate label.
    {
       lblFactorial1.Text = Value.ToString();
       // Re-enables the button so it can be used again.
       btnFactorial1.Enabled = true;
       // Updates the label that displays the total calculations performed
       lblTotalCalculations.Text = "TotalCalculations are " + 
          Calculations.ToString();
    }
    
    private void FactorialMinusHandler(double Value, double Calculations)
    {
       lblFactorial2.Text = Value.ToString();
       btnFactorial2.Enabled = true;
       lblTotalCalculations.Text = "TotalCalculations are " + 
          Calculations.ToString();
    }
    
    private void AddTwoHandler(int Value, double Calculations)
    {
       lblAddTwo.Text = Value.ToString();
       btnAddTwo.Enabled = true;
       lblTotalCalculations.Text = "TotalCalculations are " +
          Calculations.ToString();
    }
    
    private void LoopDoneHandler(double Calculations, int Count)
    {
       btnRunLoops.Enabled = true;
       lblRunLoops.Text = Count.ToString();
       lblTotalCalculations.Text = "TotalCalculations are " +
          Calculations.ToString();
    }
    
  6. في the الدالة الإنشائية of frmCalculations, إضافة the following تعليمات برمجية immediately قبل the } إلى مؤشر the مخصص أحداث your نموذج will receive من Calculator1.

    Calculator1.FactorialComplete += new
       Calculator.FactorialCompleteHandler(this.FactorialHandler);
    Calculator1.FactorialMinusOneComplete += new
       Calculator.FactorialCompleteHandler(this.FactorialMinusHandler);
    Calculator1.AddTwoComplete += new
       Calculator.AddTwoCompleteHandler(this.AddTwoHandler);
    Calculator1.LoopComplete += new
       Calculator.LoopCompleteHandler(this.LoopDoneHandler);
    

اختبار تطبيق الخاص بك

الآن تاريخ الإنشاء مشروع دمج نموذج ومكون قادراً على تنفيذ عدة عمليات حسابية معقدة. Although you have not implemented متعدد العمليات capability yet, you will اختبار your مشروع إلى verify its functionality قبل proceeding.

لاختبار المشروع الخاص بك

  1. من قائمة تصحيح ، اختيار بدء التصحيح.

    يبدأ تطبيق و frmCalculationsيظهر.

  2. في صندوق نص، ونوع 4 ، ثم انقر فوق الزر المسمى إضافة الثاني.

    يجب أن يتم عرض الرقم "6" في العنوان أسفله، و "إجمالي الحسابات 1" ينبغي أن تكون معروضة في lblTotalCalculations.

  3. الآن انقر فوق زر يسمى مضروب-1.

    The numeral "6" should be displayed beneath the زر, و lblTotalCalculations now reads "إجمالي Calculations are 4."

  4. تغيير القيمة في صندوق نص إلى 20 ، ثم انقر فوق زر يسمى حساب العاملي منه.

    The رقم "2.43290200817664E+18" هو displayed beneath it, و lblTotalCalculations now reads "إجمالي Calculations are 24."

  5. قم بتغيير القيمة في صندوق نص إلى 50000 ، ومن ثم انقر فوق زر يسمى تشغيل الحلقة A.

    لاحظ أن هناك هو فاصل زمني مربع متوسط، ولكن يمكن ملاحظته قبل th هو زر هو إعادة ممكّن. التسمية ضمن هذا زر يجب قراءة "50000" وحسابات إجمالي عرض "25000024".

  6. تغيير the القيمة في the صندوق نص إلى 5000000 و انقر the زر labeled تشغيل A تكرار حلقي, then immediately انقر the زر labeled إضافة الثاني. انقر it again.

    الزر لا يستجيب، ولا أي عنصر تحكم في النموذج سيستجيب إلى أن يتم الحلقات مكتمل.

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

إضافة إمكانية متعدد العمليات

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

إلى إضافة في الروتين الفرعي عمليات جزئية

  1. فتح آلة حاسبة.cs في the تعليمات برمجية محرر.

  2. قريب the الأعلى of the تعليمات برمجية, بحث the فئة إعلان, و immediately beneath the {, نوع the following:

    // Declares the variables you will use to hold your thread objects.
    public System.Threading.Thread FactorialThread; 
    public System.Threading.Thread FactorialMinusOneThread;  
    public System.Threading.Thread AddTwoThread; 
    public System.Threading.Thread LoopThread;
    
  3. Immediately قبل the إنهاء of the فئة إعلان at the أسفل of the تعليمات برمجية, إضافة the following أسلوب:

    public void ChooseThreads(int threadNumber)
    {
    // Determines which thread to start based on the value it receives.
    switch(threadNumber)
       {
          case 1:
             // Sets the thread using the AddressOf the subroutine where
             // the thread will start.
             FactorialThread = new System.Threading.Thread(new
                System.Threading.ThreadStart(this.Factorial));
             // Starts the thread.
             FactorialThread.Start();
             break;
          case 2:
             FactorialMinusOneThread = new
                System.Threading.Thread(new
                   System.Threading.ThreadStart(this.FactorialMinusOne));
             FactorialMinusOneThread.Start();
             break;
          case 3:
             AddTwoThread = new System.Threading.Thread(new
                 System.Threading.ThreadStart(this.AddTwo));
             AddTwoThread.Start();
             break;
          case 4:
             LoopThread = new System.Threading.Thread(new
                System.Threading.ThreadStart(this.RunALoop));
             LoopThread.Start();
             break;
       }
    }
    

    When a Thread هو instantiated, it يتطلب an وسيطة في the نموذج of a ThreadStart. The ThreadStart هو a تفويض that نقاط إلى the العنوان of the أسلوب الموقع the مؤشر ترابط هو إلى begin. A ThreadStart cannot take معلمات أو pass قيم, و therefore can فقط indicate a void أسلوب. The ChooseThreads أسلوب you just implemented will receive a القيمة من the برنامج calling it و استخدم that القيمة إلى determine the appropriate مؤشر ترابط إلى يبدأ.

إلى إضافة the appropriate تعليمات برمجية إلى frmCalculations

  1. فتح the frmCalculations.cs ملف في the تعليمات برمجية محرر, then بحث private void btnFactorial1_Click.

    1. Comment out the line that calls the Calculator1.Factorial1 method directly as shown:

      // Calculator1.Factorial()
      
    2. قم بإضافة السطر التالي إلى استدعاء Calculator1.ChooseThreadsأسلوب:

      // Passes the value 1 to Calculator1, thus directing it to start the 
      // correct thread.
      Calculator1.ChooseThreads(1);
      
  2. Make similar modifications إلى the غير ذلك button_click وظائف.

    ملاحظة

    Be certain إلى تضمين the appropriate القيمة for the Threads وسيطة.

    When you have finished, your تعليمات برمجية should look similar إلى the following:

    private void btnFactorial1_Click(object sender, System.EventArgs e)
    // Passes the value typed in the txtValue to Calculator.varFact1
    {
       Calculator1.varFact1 = int.Parse(txtValue.Text);
       // Disables the btnFactorial1 until this calculation is complete
       btnFactorial1.Enabled = false;
       // Calculator1.Factorial();
       Calculator1.ChooseThreads(1);
    }
    
    private void btnFactorial2_Click(object sender, System.EventArgs e)
    {
       Calculator1.varFact2 = int.Parse(txtValue.Text); 
       btnFactorial2.Enabled = false;         
       // Calculator1.FactorialMinusOne();
       Calculator1.ChooseThreads(2);
    }
    private void btnAddTwo_Click(object sender, System.EventArgs e)
    {
       Calculator1.varAddTwo = int.Parse(txtValue.Text);
       btnAddTwo.Enabled = false;
       // Calculator1.AddTwo();
       Calculator1.ChooseThreads(3);
    }
    
    private void btnRunLoops_Click(object sender, System.EventArgs e)
    {
       Calculator1.varLoopValue = int.Parse(txtValue.Text);
       btnRunLoops.Enabled = false;
       // Lets the user know that a loop is running
       lblRunLoops.Text = "Looping";
       // Calculator1.RunALoop();
       Calculator1.ChooseThreads(4);
    }
    

التنظيم والإرسال Calls إلى عناصر التحكم

You will now facilitate جاري الآن التحديث the عرض تشغيل the نموذج. لأن عناصر التحكم دائماً يملكها عملية جزئية الرئيسية التنفيذ، يتطلب استدعاء أي عنصر تحكم من مؤشر ترابط ثانوي مكالمة تنظيم. التنظيم والإرسال هو the act of moving a يتصل عبر مؤشر ترابط boundaries, و هو very expensive في terms of موارد. إلى تصغير the المقدار of التنظيم والإرسال that needs إلى occur, و إلى be sure that your calls are handled في a مؤشر ترابط-آمن manner, you will استخدم the Control.BeginInvoke أسلوب إلى invoke وظائف تشغيل the main مؤشر ترابط of execution, thereby minimizing the المقدار of cross-مؤشر ترابط-boundary التنظيم والإرسال that must occur. This نوع of يتصل هو necessary when calling وظائف that manipulate عناصر التحكم. للمزيد من التفاصيل ، راجع كيفية القيام بما يلي: التعامل مع عناصر التحكم من عمليات جزئية.

إلى إنشاء the عنصر تحكم-invoking إجراءات

  1. فتح the تعليمات برمجية محرر for frmCalculations. في the تصريحات مقطع, إضافة the following تعليمات برمجية:

    public delegate void FHandler(double Value, double Calculations);
    public delegate void A2Handler(int Value, double Calculations);
    public delegate void LDHandler(double Calculations, int Count);
    

    Invoke و BeginInvoke require a تفويض إلى the appropriate أسلوب كـ an وسيطة. These lines declare the تفويض signatures that will be used بواسطة BeginInvoke إلى invoke the appropriate وظائف.

  2. إضافة the following فارغ وظائف إلى your تعليمات برمجية.

    public void FactHandler(double Value, double Calculations)
    {
    }
    public void Fact1Handler(double Value, double Calculations)
    {
    }
    public void Add2Handler(int Value, double Calculations)
    {
    }
    public void LDoneHandler(double Calculations, int Count)
    {
    }
    
  3. من the تحرير قائمة, استخدم قص و لصق إلى قص الجميع the تعليمات برمجية من the أسلوب FactorialHandler و لصق it في FactHandler.

  4. تكرار the السابق step forFactorialMinusHandlerوFact1Handler,AddTwoHandlerوAdd2Handler, وLoopDoneHandlerوLDoneHandler.

    عند الانتهاء، يجب أن يكون هناك لا تعليمات برمجية المتبقية في FactorialHandler، Factorial1Handler، AddTwoHandler، و LoopDoneHandler، و الجميع التعليمة البرمجية هذه يستخدم لاحتواء يجب أن يتم نقل إلى المناسبة وظائف جديدة.

  5. باستدعاء BeginInvokeأسلوب إلى استدعاء الأساليب بشكل غير متزامن. You can يتصل BeginInvoke من either your نموذج (this) أو أي of the عناصر التحكم تشغيل the نموذج.

    When إكمال, your تعليمات برمجية should look similar إلى the following:

    protected void FactorialHandler(double Value, double Calculations)
    {
       // BeginInvoke causes asynchronous execution to begin at the address
       // specified by the delegate. Simply put, it transfers execution of 
       // this method back to the main thread. Any parameters required by 
       // the method contained at the delegate are wrapped in an object and 
       // passed. 
       this.BeginInvoke(new FHandler(FactHandler), new Object[]
          {Value, Calculations});
    }
    protected void FactorialMinusHandler(double Value, double Calculations)
    {
       this.BeginInvoke(new FHandler(Fact1Handler), new Object []
          {Value, Calculations});
    }
    
    protected void AddTwoHandler(int Value, double Calculations)
    {
       this.BeginInvoke(new A2Handler(Add2Handler), new Object[]
          {Value, Calculations});
    }
    
    protected void LoopDoneHandler(double Calculations, int Count)
    {
       this.BeginInvoke(new LDHandler(LDoneHandler), new Object[]
          {Calculations, Count});
    }
    

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

  6. حفظ العمل الخاص بك.

  7. اختبار الحل الخاص بك بواسطة تحديد بدء التصحيح من قائمة تصحيح.

    1. اكتب 10000000 في صندوق نص ثم انقر فوق تشغيل تكرار حلقي .

      "تنفيذ الحلقات" هو dهوplayed في التسمية التوضيحية أسفل th هو زر. وهذا تكرار حلقي يجب أن تأخذ مقداراً كبيرا من الوقت للتشغيل. في حالة إكمال مبكر جداً، ضبط الحجم رقم وفقا لذلك.

    2. في تتابع سريع، انقر فوق الأزرار الثلاثة التي لا تزال ممكنة. ستجد أن تستجيب الجميع butإلىns إلى الإدخال الخاص بك. يجب أن تكون التسمية أسفل إضافة الثاني أول إلى عرض نتيجة. سيتم عرض نتائج لاحقاً في التسميات أسفل الأزرار factorial. تقييم هذه نتائج إلى اللانهاية، كالرقم الذي يتم إرجاعه مضروب 10,000,000 هو كبيرة جداً على متغير double-precهوion لاحتواء. وأخيراً، بعد مهلة إضافى، يتم إرجاع نتائج تحت الزر تشغيل الحلقة A.

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

تنسيق عمليات جزئية الخاص بك

قد perceive المستخدمين ذوي خبرة من تطبيقات ذات مؤشرات ترابط متعددة خلل دقيق مع تعليمات برمجية كـ بكتابتها. Recall the lines of تعليمات برمجية من each calculation-performing أسلوب في Calculator:

varTotalCalculations += 1;
varTotalAsOfNow = varTotalCalculations;

زيادة هذه سطرين من تعليمات برمجية متغير عام varTotalCalculationsوتعيين متغير محلي varTotalAsOfNowإلى هذه القيمة. Th هو القيمة هو ثم أرجع إلى frmCalculationsdهوplayed في عنصر تحكم التسمية. ولكن هو الذي يتم إرجاع القيمة الصحيحة؟ إذا كان مسار تنفيذ واحد فقط لتنفيذ هو قيد التشغيل، والإجابة هو وضوح نعم. ولكن إذا كان يتم تشغيل مؤشرات ترابط متعددة، تصبح الإجابة المزيد متأكد أمنا. لدى كل مؤشر ترابط القدرة إلى زيادة المتغير varTotalCalculations. هو المحتملة التي بعد مؤشر ترابط واحد زيادة th هو المتغير، ولكن قبل أن يقوم بنسخ القيمة إلى varTotalAsOfNow، قد مؤشر ترابط آخر بتغيير قيمة ترتيب هو متغير بتزايد it. Th هو يؤدي إلى احتمال وجود وكل مؤشر الترابط هو، في الواقع، التقرير عن نتائج غير دقيقة. #Visual C provides the تأمين بيان (C# مرجع) إلى allow المزامنة of عمليات جزئية إلى ensure that each مؤشر ترابط دوماً إرجاع an accurate النتيجة. بناء الجملة الصحيح لـ lock هو كالتالي:

lock(AnObject)
{
   // Insert code that affects the object.
   // Insert more code that affects the object.
   // Insert more code that affects the object.
// Release the lock.
}

عند lockكتلة هو إدخال، والتنفيذ تشغيل التعبير المحدد هو حظر حتى يكون مؤشر ترابط المحدد حصرياً تشغيل الكائن في السؤال. في المثال الموضح أعلاه، تنفيذ هو حظر AnObject. lockيجب أن يستخدم مع أحد الكائنات التي تقوم بإرجاع مرجع بدلاً من القيمة. قد ثم متابعة التنفيذ ككتلة بدون تداخل من غير ذلك عمليات جزئية. التعيين من العبارات التي يتم تنفيذها كوحدة بأنها إلى يكون aإلىmic . When the } هو encountered, the تعبير هو freed و the عمليات جزئية are allowed إلى متابعة normally.

إلى إضافة the قفل كشف إلى your تطبيق

  1. فتح آلة حاسبة.cs في the تعليمات برمجية محرر.

  2. حدد موقع كل مثيل للتعليمة البرمجية التالية:

    varTotalCalculations += 1;
    varTotalAsOfNow = varTotalCalculations;
    

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

  3. تعديل تعليمات برمجية بحيث يقرأ كـ التالي:

    lock(this)
    {
       varTotalCalculations += 1;
       varTotalAsOfNow = varTotalCalculations;
    }
    
  4. قم بحفظ العمل الخاص بك واختباره كـ في المثال السابق.

    قد تلاحظ تأثير بسيط تشغيل الأداء البرنامج الخاص بك. وذلك لأنه يتوقف التنفيذ من عمليات جزئية عند الحصول تشغيل قفل للاستخدام خاص تشغيل مكوّن الخاص بك. Although it ensures accuracy, this approach impedes some of the الأداء benefits of multiple عمليات جزئية. يجب أن عناية خذ بعين الاعتبار الحاجة إلى تأمين عمليات جزئية، وتنفيذها عند الضرورة القصوى فقط.

راجع أيضًا:

المهام

كيفية القيام بما يلي: إحداثيات متعددة عمليات جزئية لتنفيذ

الإرشادات التفصيلية: تأليف بسيط ذات مؤشرات ترابط متعددة مكوّن مع Visual أساسى

المرجع

BackgroundWorker

المبادئ

تستند إلى الحدث نظرة عامة النقش غير متزامن

موارد أخرى

برمجة مع المكونات

المواضيع الإرشادية البرمجة مكوّن

متعدد العمليات في مكونات