C# 在特定情况下,如何取消backgroundWorker并重新启动backgroundWorker?
在表格1顶部:C# 在特定情况下,如何取消backgroundWorker并重新启动backgroundWorker?,c#,.net,winforms,C#,.net,Winforms,在表格1顶部: ExtractImages ei = new ExtractImages(); 在form1构造函数中,我第一次启动backgroundworker public Form1() { InitializeComponent(); backgroundWorker1.RunWorkerAsync(); } 嫁妆活动 private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
ExtractImages ei = new ExtractImages();
在form1构造函数中,我第一次启动backgroundworker
public Form1()
{
InitializeComponent();
backgroundWorker1.RunWorkerAsync();
}
嫁妆活动
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if (backgroundWorker1.CancellationPending == true)
{
e.Cancel = true;
return; // this will fall to the finally and close everything
}
else
{
ei.ProgressChanged += (senders, eee) => backgroundWorker1.ReportProgress(eee.Percentage, eee.StateText);
ei.Init();
}
}
进行中
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
ProgressBar1.Value = e.ProgressPercentage;
label7.Text = e.UserState.ToString();
label8.Text = e.ProgressPercentage + "%";
}
完成
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error == null) { ProgressBar1.Value = 100; }
else
{
}
}
在班上名列前茅
public bool WebProblem = false;
public class ProgressEventArgs : EventArgs
{
public int Percentage { get; set; }
public string StateText { get; set; }
}
public event EventHandler<ProgressEventArgs> ProgressChanged;
public void Init()
{
object obj = null;
int index = 0;
ExtractCountires();
foreach (string cc in countriescodes)
{
// raise event here
ProgressChanged?.Invoke(obj, new ProgressEventArgs { Percentage = 100 * index / countriescodes.Count, StateText = cc });
ExtractDateAndTime("http://www.sat24.com/image2.ashx?region=" + cc);
index += 1;
}
ImagesLinks();
}
我想做的是,一旦WebProblem为真,停止Init()中的循环,并停止/取消form1中的backgroundworker
然后在backgroundworker completed事件中,向标签抛出一条关于问题的消息。然后启动计时器,30秒后再次启动backgroundworker
如果异常发生,我将在catch中使用断点,然后单击继续,它将继续,但我希望一旦出现问题,停止一切,重新开始,直到中间没有任何问题。
有很多非常奇怪的东西。我建议从一开始。关于您发布内容的建议:
表单构造函数是调用的一个非常糟糕的地方。RunWorkerAsync
;特别是如果您希望能够重新启动后台进程。如果您真的想立即启动BackgroundWorker,您应该在Form\u Load方法中调用如下内容:
backgroundWorker1.RunWorkerAsync(new Uri("http://www.sat24.com/image2.ashx"));
你的dowworkeventhandler
是你应该做背景工作、检查取消情况和报告结果的地方,而你没有做任何这些。你想要的是:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var result = new List<DateString>();
var baseUri = (Uri)e.Argument;
var countryCodes = ExtractCountries();
foreach (var cc in countryCodes)
{
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
return;
}
result.Add(ExtractDateAndTime(new Uri(baseUri, "?region=" + cc));
}
e.Result = result;
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
backgroundWorker1.RunWorkerAsync(new Uri("http://www.sat24.com/image2.ashx"));
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
AlertUserSomehow(e.Error);
timer1.Interval = 30000;
timer1.Start();
return;
}
DoSomethingWith((List<DateString>)e.Result);
}
不要捕获提取日期和时间中的异常;这样做将放弃异常并继续,就好像什么都没有错一样,然后在没有警告的情况下返回错误的答案。如果要显示异常,请将其传播到RunWorkerCompleted
事件,并检查RunWorkerCompletedEventArgs.Error
如果要重新启动BackgroundWorker
,如果出现错误,则需要在设计视图或表单构造函数中声明窗体.Timer
,以及勾选事件处理程序,例如:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var result = new List<DateString>();
var baseUri = (Uri)e.Argument;
var countryCodes = ExtractCountries();
foreach (var cc in countryCodes)
{
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
return;
}
result.Add(ExtractDateAndTime(new Uri(baseUri, "?region=" + cc));
}
e.Result = result;
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
backgroundWorker1.RunWorkerAsync(new Uri("http://www.sat24.com/image2.ashx"));
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
AlertUserSomehow(e.Error);
timer1.Interval = 30000;
timer1.Start();
return;
}
DoSomethingWith((List<DateString>)e.Result);
}
在您的RunWorkerCompletedEventHandler中执行以下操作:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var result = new List<DateString>();
var baseUri = (Uri)e.Argument;
var countryCodes = ExtractCountries();
foreach (var cc in countryCodes)
{
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
return;
}
result.Add(ExtractDateAndTime(new Uri(baseUri, "?region=" + cc));
}
e.Result = result;
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
backgroundWorker1.RunWorkerAsync(new Uri("http://www.sat24.com/image2.ashx"));
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
AlertUserSomehow(e.Error);
timer1.Interval = 30000;
timer1.Start();
return;
}
DoSomethingWith((List<DateString>)e.Result);
}
private void backgroundWorker1\u RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{
如果(例如错误!=null)
{
警报(例如错误);
计时器1.间隔=30000;
timer1.Start();
返回;
}
带有((列表)e.结果)的dosomething;
}
从DoWork
处理程序内部连接ProgressChanged
事件处理程序没有任何意义。两者都必须从UI线程设置。确定。。。我懂了。您有两个级别的事件。若要重新启动,则在“已完成的处理程序”中,检查是否需要重新启动。。。有什么问题?