暂停和在C#中恢复一个for循环 [英] Pause and Resume a For-Loop in C#

查看:320
本文介绍了暂停和在C#中恢复一个for循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个Windows应用程序在C#中,我有一个循环for循环哪个更新的东西,我有一个名为停止,暂停,恢复表单上的3个按键。因此,其目的是为命名的按钮相同。有谁知道如何做到这一点?



下面是循环

 私人无效btnCompleteAuto_Click(对象发件人,EventArgs五)
{
setGeneralValue();
的for(int i = 1; I< = autoGridView.Rows.Count - 1;我++)
{
如果(SRP ==暂停)//这是我思维,但它不会工作,
{//将步入年底少环
做//如何制止这一循环恢复按钮,点击
{

},而(SRP =恢复!)

}
车= FALSE;

{
MEMBERID = Convert.ToInt64(autoGridView.Rows [0] .Cells [Member_ID]值。);
DISPID = Convert.ToString(autoGridView.Rows [0] .Cells [Disp_Id]值。);
=移动Convert.ToString(autoGridView.Rows [0] .Cells [手机]值。);
DUEDATE = Convert.ToString(autoGridView.Rows [0] .Cells [DUE_DATE]值。);

}
赶上(例外)
{
MessageBox.Show(未找到行);
}

AutoRecharge(网络名,pack_name,手机,移动,Convert.ToString(autoGridView.Rows [0] .Cells [Rck_Amt]。值),VENDOR_ID,vendor_pwd,pack_id, oxinetwork_id);
autoGridView.Rows.RemoveAt(0);
}
}

下面是在我的3按钮事件设置变量

 私人无效btnPause_Click(对象发件人,EventArgs五)
{
SRP =暂停
}

私人无效btnStop_Click(对象发件人,EventArgs五)
{
SRP =停止;
autoGridView.DataSource =;
}

私人无效btnResume_Click(对象发件人,EventArgs五)
{
SRP =恢复;
}


解决方案

究其原因,这并不如你期望的工作是这样的:



一个Windows窗体应用程序使用的的UI线程,不断地从队列处理传入的消息。您连接到一个Windows窗体的事件的任何事件处理程序控件得到迅速发送到此队列和处理UI线程越好。



btnCompleteAuto_Click 就是这样的一个处理程序。一旦开始,不出意外将被UI线程直到它退出的处理。因此,任何的其他的附加到处理程序的其他的事件( btnPause_Click btnStop_Click 等),必须等待轮到他们,因为他们将在相同的(UI)线程上运行。



如果你想暂停/恢复功能,这的上一个单独的线程来实现。



要实现它可能会使用的BackgroundWorker ,因为由SAURABH



下面是一个粗糙的的更新的代码可能是什么样子(我还没有尝试素描的编译此,更不用说调试它;它的目的只是为如何完成这个功能),一个基本的轮廓。



您需要注意,但是,访问UI控件直接从非UI线程是一个没有没有。使用一种机制,如 BackgroundWorker.ProgressChanged 事件来处理,你需要根据一个非UI线程活动发生任何UI更新。

  ManualResetEvent的_busy =新的ManualResetEvent(假); 

私人无效btnCompleteAuto_Click(对象发件人,EventArgs五)
{
如果
{
_busy.Set()(backgroundWorker.IsBusy!);
btnAutoCompleteAuto.Text =暂停;
backgroundWorker.RunWorkerAsync();
}
,否则
{
_busy.Reset();
btnAutoCompleteAuto.Text =恢复;
}

btnStop.Enabled = TRUE;
}

私人无效btnStop_Click(对象发件人,EventArgs五)
{
_busy.Set();
backgroundWorker.CancelAsync();
}

私人无效backgroundWorker_DoWork(对象发件人,DoWorkEventArgs E)
{
//(某事)
// {

_busy.WaitOne();

如果(backgroundWorker.CancellationPending)
{
的回报;
}

//在这里做你的工作。

//}
}

私人无效backgroundWorker_RunWorkerCompleted(对象发件人,RunWorkerCompletedEventArgs E)
{
_busy.Reset();
btnAutoCompleteAuto.Text =开始;
btnStop.Enabled = FALSE;
}


I'm working on a windows App in C#, I have a for-loop which update something in a loop, and I have 3 buttons on the form named "Stop,Pause,Resume". So the purpose is as same as the buttons named. Does anyone know how to do this?

Here is the Loop

    private void btnCompleteAuto_Click(object sender, EventArgs e)
    {
        setGeneralValue();
        for (int i = 1; i <= autoGridView.Rows.Count - 1; i++)
        {
            if (SRP == "Pause") // this is what I was thinking but it won't work
            {                   // it will step into end-less loop
              do                // how to stop this loop on "Resume" button click
              {

              }while(SRP!="Resume")

            }
            car = false;
            try
            {
                MemberID = Convert.ToInt64(autoGridView.Rows[0].Cells["Member_ID"].Value);
                DispID = Convert.ToString(autoGridView.Rows[0].Cells["Disp_Id"].Value);
                Mobile = Convert.ToString(autoGridView.Rows[0].Cells["Mobile"].Value);
                DueDate = Convert.ToString(autoGridView.Rows[0].Cells["Due_Date"].Value);

            }
            catch (Exception)
            {
                MessageBox.Show("Row Not Found");
            }

            AutoRecharge(network_name, pack_name, Mobile, Mobile, Convert.ToString(autoGridView.Rows[0].Cells["Rck_Amt"].Value), vendor_id, vendor_pwd, pack_id, oxinetwork_id);
            autoGridView.Rows.RemoveAt(0);
        }
    }

Here are the 3 button events in which I'm setting a variable

    private void btnPause_Click(object sender, EventArgs e)
    {
        SRP = "Pause";
    }

    private void btnStop_Click(object sender, EventArgs e)
    {
        SRP = "Stop";
        autoGridView.DataSource = "";
    }

    private void btnResume_Click(object sender, EventArgs e)
    {
        SRP = "Resume";
    }

解决方案

The reason this doesn't work as you expect is this:

A Windows Forms application uses a single UI thread, which continually processes incoming messages from a queue. Any event handlers you attach to the events of a Windows Forms control get sent to this queue and processed by the UI thread as quickly as possible.

Your btnCompleteAuto_Click is one such handler. Once it starts, nothing else will be processed by the UI thread until it exits. Thus any other handlers you attach to other events (btnPause_Click, btnStop_Click, etc.) must wait their turn, as they will run on the same (UI) thread.

If you want pause/resume functionality, this has to be achieved on a separate thread.

A possible way to implement it might be to use a BackgroundWorker, as suggested by saurabh.

Here is a rough sketch of what your updated code might look like (I have not even attempted to compile this, let alone debug it; it's intended only as a basic outline of how you might accomplish this functionality).

You need to be aware, however, that accessing UI controls directly from a non-UI thread is a no-no. Use a mechanism such as the BackgroundWorker.ProgressChanged event to handle any UI updates that you need to happen based on activity on a non-UI thread.

ManualResetEvent _busy = new ManualResetEvent(false);

private void btnCompleteAuto_Click(object sender, EventArgs e)
{
    if (!backgroundWorker.IsBusy)
    {
        _busy.Set();
        btnAutoCompleteAuto.Text = "Pause";
        backgroundWorker.RunWorkerAsync();
    }
    else
    {
        _busy.Reset();
        btnAutoCompleteAuto.Text = "Resume";
    }

    btnStop.Enabled = true;
}

private void btnStop_Click(object sender, EventArgs e)
{
    _busy.Set();
    backgroundWorker.CancelAsync();
}

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    // for (something)
    // {

        _busy.WaitOne();

        if (backgroundWorker.CancellationPending)
        {
            return;
        }

        // Do your work here.

    // }
}

private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    _busy.Reset();
    btnAutoCompleteAuto.Text = "Start";
    btnStop.Enabled = false;
}

这篇关于暂停和在C#中恢复一个for循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆