C# 从窗体关闭触发时,RunWorkerCompleted未触发
我有一个表单需要通过web服务调用将未保存的数据保存到外部DB。当用户手动保存数据时,会触发RunWorkerCompleted,但在我通过FormClosing事件调用该方法时不会触发 在用户修改表单中的一个值后,计时器会在几秒钟后滴答作响,如果用户修改了另一个值,计时器就会重置,因为“toSend”列表有多个值,而且我可以一次发布多个更改,因为web服务调用会带来大量开销C# 从窗体关闭触发时,RunWorkerCompleted未触发,c#,forms,timer,backgroundworker,formclosing,C#,Forms,Timer,Backgroundworker,Formclosing,我有一个表单需要通过web服务调用将未保存的数据保存到外部DB。当用户手动保存数据时,会触发RunWorkerCompleted,但在我通过FormClosing事件调用该方法时不会触发 在用户修改表单中的一个值后,计时器会在几秒钟后滴答作响,如果用户修改了另一个值,计时器就会重置,因为“toSend”列表有多个值,而且我可以一次发布多个更改,因为web服务调用会带来大量开销 private void timer1_Tick(object sender, EventArgs e)
private void timer1_Tick(object sender, EventArgs e)
{
if (PublishBackgroundWorker.IsBusy)
return;
List<object> toSend = new List<object>();
// Figure out what changed and add it to toSend ...
toSend.Add(changedItems);
if (toSend.Count >= 1)
PublishBackgroundWorker.RunWorkerAsync(toSend);
}
private void PublishBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (((List<object>)(e.Argument)).Count > 0)
{
Service.SrvObjects[] ret = Svc.PublishItems(e.Argument));
}
}
private void PublishBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Invoke(new UpdateStatusCallback(this.UpdateStatus), new object[] { "Ready" });
}
private void IPTUserInterfaceForm_FormClosing(object sender, FormClosingEventArgs e)
{
timer1.Enabled = false;
timer1_Tick(this, new EventArgs());
//Application.DoEvents();
while (PublishBackgroundWorker.IsBusy)
System.Threading.Thread.Sleep(100);
}
private void timer1\u勾选(对象发送方,事件参数e)
{
if(PublishBackgroundWorker.IsBusy)
返回;
List toSend=新列表();
//找出更改的内容并将其添加到toSend。。。
toSend.Add(changedItems);
如果(toSend.Count>=1)
PublishBackgroundWorker.RunWorkerAsync(toSend);
}
私有void PublishBackgroundWorker_DoWork(对象发送方,DoWorkEventArgs e)
{
如果(((列表)(如参数)).Count>0)
{
Service.SrvObjects[]ret=Svc.PublishItems(e.Argument));
}
}
private void PublishBackgroundWorker_RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{
调用(newupdatestatuscallback(this.UpdateStatus),新对象[]{“Ready”});
}
私有void IPTUserInterfaceForm_FormClosing(对象发送方,FormClosingEventArgs e)
{
timer1.Enabled=false;
timer1_勾选(这是新的EventArgs());
//Application.DoEvents();
while(PublishBackgroundWorker.IsBusy)
系统线程线程睡眠(100);
}
这有意义吗?当用户更改一个值,并在计时器关闭之前关闭表单时,我手动勾选PublishBackgroundWorker.IsBusy在某个点上为false,这绝不是因为从未调用RunWorkerCompleted。问题是,您的Backgroundworker不忙,只是因为您调用了timerTick方法。因此,在方法的其余部分运行完毕、表单关闭以及应用程序关闭之前,永远不会到达此代码:
while (PublishBackgroundWorker.IsBusy)
System.Threading.Thread.Sleep(100);
我看不出你为什么要从
PublishBackgroundWorker\u runworker completed
中调用Invoke
。这只是向用户更新到服务器的发布已完成。由于它在一个单独的线程上,我需要一个代理来更新表单上的文本。。。。公共委托void UpdateStatusCallback(字符串文本);private void UpdateStatus(string text){StatusStripLabel.text=text;System.Threading.Thread.Sleep(5);}第一反应:听起来好像您错过了一个调用。另请参见,但后台工作线程RunWorkerAsync在Timer_Tick中被调用,这不会触发工作线程运行,因此该线程需要在DoWork完成后调用RunWorkerCompleted?请尝试放置一个thread.Sleep(100)代码>代码中有//Application.DoEvents()的地方代码>。。。我想这是比赛条件,明白了。。。如果我将应用程序.DoEvents
与Sleep放在while循环中,它就会工作。我明白了。谢谢