在C#中没有触发的后台工作线程完成事件 [英] Background worker thread complete event not fired in C#

查看:106
本文介绍了在C#中没有触发的后台工作线程完成事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





在我的应用程序中,我使用了backgroundworker线程进行了一些后台处理。线程调用成功,Dowork事件完成了他的所有工作。但是,在Dowork事件完成后,RunWorkerCompleted事件没有被解雇。对此有任何建议会很棒。



这里我附上了我的示例代码片段。



我尝试过:



MainForm.cs:



 public partial class MainForm:Form 
{

public Form1()
{
InitializeComponent();

InspectorWrapperThread wraperThread = new InspectorWrapperThread();
wraperThread.Start();
}
}





InspectorWrapperThread.cs



 public class InspectorWrapperThread:IDisposable 
{

BackgroundWorker worker1;

public InspectorWrapperThread()
{

worker1 = new BackgroundWorker();
worker1.WorkerSupportsCancellation = true;
worker1.DoWork + =新的DoWorkEventHandler(worker1_DoWork);
worker1.RunWorkerCompleted + = new RunWorkerCompletedEventHandler(worker1_RunWorkerCompleted);
}

void worker1_DoWork(对象发送者,DoWorkEventArgs e)
{
从这里调用一个函数。
function1(true);
//在这里做一些工作
}

void worker1_RunWorkerCompleted(对象发送者,RunWorkerCompletedEventArgs e)
{
//正确调用此线程完成。
}

private void function1(bool exe)
{
//做一些操作并调用下面的函数。
WorkerThread2 worker = new WorkerThread2();
worker.function2();
}
}



WorkerThread2.cs



 public class WorkerThread2:IDisposable 
{
private BackgroundWorker backgroundWorkerThread2Tab;

public WorkerThread2()
{
backgroundWorkerThread2Tab = new BackgroundWorker();
backgroundWorkerThread2Tab.WorkerSupportsCancellation = true;
backgroundWorkerThread2Tab.DoWork + =新的DoWorkEventHandler(backgroundWorkerThread2TabDoWork);
backgroundWorkerThread2Tab.RunWorkerCompleted + = new RunWorkerCompletedEventHandler(backgroundWorkerThread2TabRunWorkerCompleted);
}

public void function2()
{
//做一些操作并调用函数。

HitAPIcalls();
}

private void HitAPIcalls()
{
//做一些操作并调用
if(!backgroundWorkerThread2Tab.IsBusy)
backgroundWorkerThread2Tab .RunWorkerAsync(邮件);
}

void backgroundWorkerThread2TabDoWork(对象发送者,DoWorkEventArgs e)
{
//成功调用此Dowork事件并完成所有操作,没有任何问题。
}

void backgroundWorkerThread2TabRunWorkerCompleted(对象发送者,RunWorkerCompletedEventArgs e)
{
//这个线程完成永远不会被调用。
}
}





如果任何地址问题在这里会很棒。



提前谢谢。

解决方案

你实际上根本没有启动第二个线程。最有可能的是,那是因为您已经过编辑了代码 - 但是如果正在调用DoWork事件(并且您说它有效),那么您需要仔细查看DoWork事件处理程序中的代码。只有在DoWork处理程序存在时才会处理Completed事件 - 所以如果其上的代码位于循环中而不是返回,则线程永远不会结束,因此永远不会调用处理程序。


基于评论中的代码到解决方案#1:



InspectorWrapperThread.cs

  while (!worker.canCompleteThread)
{
if (worker.canCompleteThread)
{
break ;
}
Thread.Sleep( 10 );
}

WorkerThread2.cs

  public   bool  canCompleteThread =  false ; 
...
void backgroundWorkerThread2TabRunWorkerCompleted( object sender,RunWorkerCompletedEventArgs e)
{
canCompleteThread = true
}



您需要制作 canCompleteThread 字段 volatile

  public   volatile   bool  canCompleteThread =  false ; 

volatile(C#参考)| Microsoft Docs [ ^ ]


Hi,

In my application, I have used the backgroundworker thread for some background process. The thread called successfully and the Dowork event done all of his work. But, after completion of the Dowork event the RunWorkerCompleted event not getting fired. Any suggestion on this it would be great.

Here I have attached my sample code snippet.

What I have tried:

MainForm.cs:

public partial class MainForm : Form
 { 	
  
	public Form1()
	{
		InitializeComponent();
		
		InspectorWrapperThread wraperThread = new InspectorWrapperThread();
        wraperThread.Start();
	}
 }



InspectorWrapperThread.cs

public class InspectorWrapperThread : IDisposable
 {
 
	BackgroundWorker worker1;
	
	public InspectorWrapperThread()
	{

		worker1 = new BackgroundWorker();
		worker1.WorkerSupportsCancellation = true;
		worker1.DoWork += new DoWorkEventHandler(worker1_DoWork);
		worker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker1_RunWorkerCompleted);
	}
 
	 void worker1_DoWork(object sender, DoWorkEventArgs e)
	 {
		Called a function from here.
		function1(true);
		//Do some work here
	 }
	 
	 void worker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
	 {
		// This thread completion getting called correctly. 
	 }
	 
	 private void function1(bool exe)
	 {
		// do some operation and call the function like below.
		WorkerThread2 worker = new WorkerThread2();
		worker.function2();
	 }
 }


WorkerThread2.cs

public class WorkerThread2 : IDisposable
 {
	private BackgroundWorker backgroundWorkerThread2Tab;
	
	public WorkerThread2()
	{
		backgroundWorkerThread2Tab = new BackgroundWorker();
		backgroundWorkerThread2Tab.WorkerSupportsCancellation = true;
		backgroundWorkerThread2Tab.DoWork += new DoWorkEventHandler(backgroundWorkerThread2TabDoWork);
		backgroundWorkerThread2Tab.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorkerThread2TabRunWorkerCompleted);
	}
	
	public void function2()
	{
		// do some operation and call the function.
		
		HitAPIcalls();
	}
	
	private void HitAPIcalls()
	{
		// do some operation and call
		if (!backgroundWorkerThread2Tab.IsBusy)
                backgroundWorkerThread2Tab.RunWorkerAsync(mail);
	}
	
	void backgroundWorkerThread2TabDoWork(object sender, DoWorkEventArgs e)
	 {
		//This Dowork event getting called successfully and do all the operation without any issues.
	 }
	 
	 void backgroundWorkerThread2TabRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
	 {
		// This thread completion never getting called.
	 }
 }



If any address the issue here it would be great.

Thanks in advance.

解决方案

You don't actually start the second thread at all. Most likely, that's because you have over redacted the code - but if the DoWork event is being called (and you say it works) then you need to look very closely at the code you have in the DoWork event handler. The Completed event will only ever get handled when the DoWork handler exist - so if the code on that sits in a loop instead of returning then the thread never ends, so teh handler is never called.


Based on the code from the comments to solution #1:

InspectorWrapperThread.cs:

while (!worker.canCompleteThread)
{
    if (worker.canCompleteThread)
    {
        break;
    }
    Thread.Sleep(10);
}

WorkerThread2.cs:

public bool canCompleteThread = false;
...
void backgroundWorkerThread2TabRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    canCompleteThread = true
}


You need to make the canCompleteThread field volatile:

public volatile bool canCompleteThread = false;

volatile (C# Reference) | Microsoft Docs[^]


这篇关于在C#中没有触发的后台工作线程完成事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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