سؤال

لدي تطبيق C# يحتوي على واجهة المستخدم ومواضيع الخلفية. استنادًا إلى إدخال المستخدم ، أود إيقاف وبدء مؤشر ترابط الخلفية. لدي خياران هنا كما أرى:

1) توقف تمامًا ثم ابدأ موضوع الخلفية كخيط جديد (لم أتمكن من ذلك. أستمر في الحصول على رسالتي المنتهية)

2) إيقاف مؤشر ترابط الخلفية حتى انقر فوق المستخدم مرة أخرى.

فيما يلي الرمز الذي أتصل به مرة أخرى بعد bw.cancelasync () ؛

    private void StartBackgroundWorker()
    {
        bw = new BackgroundWorker();
        bw.WorkerReportsProgress = true;
        bw.WorkerSupportsCancellation = true;
        bw.DoWork += bw_DoWork;
        bw.RunWorkerCompleted += bw_RunWorkerCompleted;
        bw.RunWorkerAsync("Background Worker");
    }

شكرا مقدما لمساعدتكم.

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

المحلول

لا يمكنك البدء وإيقاف عامل في الخلفية من هذا القبيل ، ولكن في حدث Dowork الخاص بك ، يمكنك أن تسأل عما إذا كان ينبغي تنفيذها أو الانتظار.

يمكنك أيضًا أن يكون عمال الخلفية الفرعي (تجاوز طريقة OnDowork ()) ، وإضافة طرق بدء/إيقاف مؤقت إلى تبديل مقبض انتظار خاص ، وهو أجمل بكثير من معرفة واجهة المستخدم الخاصة بك عن ManualResetEvent.

//using System.Threading;

//the worker will ask this if it can run
ManualResetEvent wh = new ManualResetEvent(false);

//this holds UI state for the start/stop button
bool canRun = false;

private void StartBackgroundWorker()
{
    bw = new BackgroundWorker();
    bw.WorkerReportsProgress = true;
    bw.WorkerSupportsCancellation = true;
    bw.DoWork += bw_DoWork;
    bw.RunWorkerCompleted += bw_RunWorkerCompleted;
    bw.RunWorkerAsync("Background Worker");
}


void bw_DoWork(object sender, DoWorkEventArgs e)
{
     while(true) 
     {
          //it waits here until someone calls Set() on wh  (via user input)
          // it will pass every time after that after Set is called until Reset() is called
          wh.WaitOne()

         //do your work

     }
}


//background worker can't start until Set() is called on wh
void btnStartStop_Clicked(object sender, EventArgs e)
{
    //toggle the wait handle based on state
    if(canRun)
    {
        wh.Reset();
    }
    else {wh.Set();}

    canRun= !canRun;
    //btnStartStop.Text = canRun ? "Stop" : "Start";
}

نصائح أخرى

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

حل آخر هو أن يرث من فئة الخيوط ، وإضافة وظيفة إلى هذه الفئة التي تتوقف أو توقف الخيط. بهذه الطريقة يمكنك إخفاء تفاصيل التنفيذ.

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