暂停和在C#中恢复一个for循环 [英] Pause and Resume a For-Loop in C#
问题描述
我工作的一个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 $一种可能的方法C $ C>,因为由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屋!