Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#后台工作人员有时需要很长时间才能开始工作_C#_Multithreading_Backgroundworker - Fatal编程技术网

C#后台工作人员有时需要很长时间才能开始工作

C#后台工作人员有时需要很长时间才能开始工作,c#,multithreading,backgroundworker,C#,Multithreading,Backgroundworker,我发现我使用BackgroundWorker有问题。发生的情况是BackgroundWorker流程将正常工作,然后偶尔需要大约40-50秒才能开始 问题发生在两台机器上。BackgroundWorker操作一整天都在正常工作,然后在下午开始出现此问题,该过程将花费40秒而不是1秒,但只是偶尔发生。你可以做5个,第6个需要40秒。然后你可以再做5次。如果开始的时间超过一秒钟,您只需在workingDialog上按cancel,然后立即再次执行,即可正常工作。经进一步检查,工人似乎没有立即开始使用

我发现我使用BackgroundWorker有问题。发生的情况是BackgroundWorker流程将正常工作,然后偶尔需要大约40-50秒才能开始

问题发生在两台机器上。BackgroundWorker操作一整天都在正常工作,然后在下午开始出现此问题,该过程将花费40秒而不是1秒,但只是偶尔发生。你可以做5个,第6个需要40秒。然后你可以再做5次。如果开始的时间超过一秒钟,您只需在workingDialog上按cancel,然后立即再次执行,即可正常工作。经进一步检查,工人似乎没有立即开始使用定位销方法

我的线程可能用完了吗?或者可能是我如何处理后台工作人员的问题?代码如下

using (workingDialog = new Dialogs.WaitDialog()) {
    StartThreadedWork(MyDoWorkMethod, customerID);

    // if user presses cancel button
    if (workingDialog.ShowDialog() == System.Windows.Forms.DialogResult.Cancel) {
        m_Worker.RunWorkerCompleted -= ThreadFinished;
    }
}
m_Worker.Dispose();
m_Worker = null;
private void StartThreadedWork(DoWorkEventHandler method, int customerID) {
    m_Worker = new BackgroundWorker();
    m_Worker.DoWork += method;
    m_Worker.RunWorkerCompleted += ThreadFinished;
    object[] parameters = new object [] {customerID };
    m_Worker.RunWorkerAsync(parameters);
}
“StartThreadedWork”方法如下所示

using (workingDialog = new Dialogs.WaitDialog()) {
    StartThreadedWork(MyDoWorkMethod, customerID);

    // if user presses cancel button
    if (workingDialog.ShowDialog() == System.Windows.Forms.DialogResult.Cancel) {
        m_Worker.RunWorkerCompleted -= ThreadFinished;
    }
}
m_Worker.Dispose();
m_Worker = null;
private void StartThreadedWork(DoWorkEventHandler method, int customerID) {
    m_Worker = new BackgroundWorker();
    m_Worker.DoWork += method;
    m_Worker.RunWorkerCompleted += ThreadFinished;
    object[] parameters = new object [] {customerID };
    m_Worker.RunWorkerAsync(parameters);
}
最后,分配给DoWork事件处理程序的方法是:

private void ThreadSyncing(object sender, DoWorkEventArgs e) {
    object[] parameters = e.Argument as object[];
    int customerID = (int)parameters[0];
    Customer resultCustomer = new Customer(FormsManager.Instance.BillingWebService.Customer_GetByCustomerID(customerID, CustomerSyncOption.Default));
    e.Result = resultCustomer;
}
触发RunWorkerCompleted事件后,对话框结果设置为OK,对话框关闭

任何关于这一点的建议都将非常感谢


谢谢,

BackgroundWorker使用.Net线程池执行其DoWork方法


如果您在线程池上施加了太多的负载,一些工作项将被延迟,直到它有一个可用的线程来处理它们。

您如何知道实际上是BGW的启动被延迟了?你没有给出任何反馈,你所能看到的只是它完成了。看起来您正在使用web服务,服务器没有响应或完成请求,持续40秒并不异常。默认tcp/ip连接超时为45秒

线程池调度程序可以扮演一个角色,它尝试将执行TP线程的数量限制为机器拥有的cpu内核数量。然而,获得40秒的延迟是一个严重的问题。调度程序允许在现有线程未完成时启动另一个TP线程,每秒两次。因此,您必须有80个活动的TP线程才能产生这样的延迟

您使用的对话框中值得注意的一点是,它实际上并没有停止工作线程。它只是放弃了它。因此,如果服务器没有响应,用户变得不耐烦,那么您可能会得到构建。轻拍她的脚四次后,反复按下取消按钮。这确实会导致不断增加的延误。您应该使用CancelAsync()方法,并使用CancellationPending属性实现取消逻辑。但是是的,使用web服务通常不容易做到这一点


通过提供更好的反馈来解决这个问题。当用户取消时,不要取消订阅RunWorkerCompleted事件。只需设置一个标志,指示上次请求已取消。在UI中显示web服务在worker完成之前不可用。包括不允许用户再次启动web服务请求。

如果使用池中最后一个可用线程,然后调用
BackgroundWorker.RunWorkerAsync
,则可能发生这种情况。线程池将至少需要1秒来创建一个新线程(假设另一个线程在此期间不可用)。如果CPU负载很重,那1秒可能会更长。有没有办法查看/增加可用线程的数量?然而,这会让我觉得我正在改变一些东西,以适应糟糕的设计。如果我删除线程,只调用webservice,它就会一直工作,而且永远不会超时。因此,我有理由相信这不是web服务超时。在请求完成之前不允许用户再次启动请求的问题是,他们必须等待40秒才能完成该线程。正如我所说,如果我移除线程,它每次都会工作。这样做的唯一问题是,如果由于某种原因Web服务关闭或失去连接,UI将停止响应:-(谢谢你的回复!我不是说web服务超时,我是指用户超时。给她一个取消按钮,她会使用它。另外……我不确定我是否只是在看这个并试图找到一些东西……但是因为我在调用'ShowDialog()之前开始了“startThreadedWork”“…线程可能正在完成,并且设置dialogresult的速度太快,以至于'ShowDialog()'还没有启动,因此没有侦听dialogresult的更改…”不太可能,但我看不到您的RunWorkerCompleted事件处理程序。我想说,是时候在代码中添加一些日志记录,以便记录发生的情况了。