C# BackgroundWorker 在完成之前完成调用方式
C# BackgroundWorker Completed Called Way Before Completion
我一直在努力弄清楚为什么我的后台工作人员 'finishing' 在它还有很多工作要做的时候工作。我实际上正在重构这个应用程序的代码,所以它过去确实有效,但现在我无法弄清楚哪里出了问题。
具体而言,该应用应打开 Outlook,然后执行一些检查。但是,后台工作人员在打开 Outlook 后立即退出,原因不明(正如您将在下面看到的那样,仍有大量处理工作要做)。
这似乎发生在 Start()
方法的早期,直接在 Outlook.exe 上调用 Process.Start()
之后。
代码按以下顺序运行:
calling the background worker - this was the user's choice from a radio set
....
else if (radioButton5.Checked == true)
{
textBox1.Text = "Please wait while your session restarts";
pageControl1.SelectedIndex = 10;
backgroundReset.RunWorkerAsync();
}
The do-work method
public void backgroundReset_DoWork(object sender, DoWorkEventArgs e)
{
backgroundReset.WorkerSupportsCancellation = true;
Session.Reset();
}
the reset session method starts by killing the current session ...
public static void Reset()
{
KillSession();
System.Threading.Thread.Sleep(5000);
Start();
// THE BACKGROUNDWORKER EXITS BEFORE HERE!
if (IsLoggedIn() == false)
{
return;
}
else
{
// Make sure Lync is open before finishing the process ...
var j = 0;
GetSession(Init.servers);
j = 0;
var checker = false;
checker = ProcessHandler.CheckRunning("lync.exe");
while (checker == false)
{
if (j == 100)
{
break;
}
Thread.Sleep(500);
checker = ProcessHandler.CheckRunning("lync.exe");
j++;
}
}
}
正如您从评论中看到的,backgroundworder 在 Reset() 方法完成执行之前调用了 RunWorkerCompleted 方法。
下面是调用的其他方法(终止、注销、启动):
KillSession logs the session of and then makes sure it is logged off
private static void KillSession()
{
if (sessionId != null)
{
LogOff();
for (int i = 0; i < 150; i++)
{
if (IsLoggedIn() == true)
{
Thread.Sleep(500);
}
else
{
break;
}
}
}
}
LogOff sends a Cmd command to log off the current session
public static void LogOff()
{
string strCmdIn = "/C LOGOFF " + sessionId + " /SERVER:" + serverName;
Cmd.Exec(strCmdIn);
}
Start() Simply opens Outlook, causing a Citrix session to also start. The app is definitely launching Outlook, but after that it doesn't reach either of the for statements - the BackgroundWorker just exits.
public static void Start()
{
Process.Start(appDataCitrix + "Outlook.exe");
for (int i = 0; i < 15; i++)
{
if (IsLoggedIn2() == false)
{
Thread.Sleep(1000);
}
else
{
break;
}
}
if (IsLoggedIn2() == false)
{
Process.Start(appDataCitrix + "Outlook.exe");
for (int i = 0; i < 10; i++)
{
if (IsLoggedIn2() == false)
{
Thread.Sleep(1000);
}
else
{
break;
}
}
}
}
有人知道这里发生了什么吗?这让我发疯!
非常感谢
更新
The RunWorkerCompleted Method:
As far as my understanding goes, this has no baring on when the process will finish.
public void backgroundReset_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (Session.IsLoggedIn())
{
btnFailFinish.Visible = true;
label10.Text = Session.serverName;
pageControl1.SelectedIndex = 3;
}
else
{
pageControl1.SelectedIndex = 10;
pictureBox2.Visible = false;
textBox1.Text = "Double-click Outlook on your desktop to launch a new session.";
textBox15.Text = "Once you have done this please click Finish.";
pictureBox9.Visible = true;
}
}
这可能是因为 start
方法中抛出了异常。
您可以在该方法周围添加一个 try / catch 块并从 catch 中处理错误,或者如果发生异常则检查 RunWorkerCompleted 方法:
private void RunWorkerCompleted (object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
// handle your exception here
}
}
我一直在努力弄清楚为什么我的后台工作人员 'finishing' 在它还有很多工作要做的时候工作。我实际上正在重构这个应用程序的代码,所以它过去确实有效,但现在我无法弄清楚哪里出了问题。
具体而言,该应用应打开 Outlook,然后执行一些检查。但是,后台工作人员在打开 Outlook 后立即退出,原因不明(正如您将在下面看到的那样,仍有大量处理工作要做)。
这似乎发生在 Start()
方法的早期,直接在 Outlook.exe 上调用 Process.Start()
之后。
代码按以下顺序运行:
calling the background worker - this was the user's choice from a radio set
....
else if (radioButton5.Checked == true)
{
textBox1.Text = "Please wait while your session restarts";
pageControl1.SelectedIndex = 10;
backgroundReset.RunWorkerAsync();
}
The do-work method
public void backgroundReset_DoWork(object sender, DoWorkEventArgs e)
{
backgroundReset.WorkerSupportsCancellation = true;
Session.Reset();
}
the reset session method starts by killing the current session ...
public static void Reset()
{
KillSession();
System.Threading.Thread.Sleep(5000);
Start();
// THE BACKGROUNDWORKER EXITS BEFORE HERE!
if (IsLoggedIn() == false)
{
return;
}
else
{
// Make sure Lync is open before finishing the process ...
var j = 0;
GetSession(Init.servers);
j = 0;
var checker = false;
checker = ProcessHandler.CheckRunning("lync.exe");
while (checker == false)
{
if (j == 100)
{
break;
}
Thread.Sleep(500);
checker = ProcessHandler.CheckRunning("lync.exe");
j++;
}
}
}
正如您从评论中看到的,backgroundworder 在 Reset() 方法完成执行之前调用了 RunWorkerCompleted 方法。
下面是调用的其他方法(终止、注销、启动):
KillSession logs the session of and then makes sure it is logged off
private static void KillSession()
{
if (sessionId != null)
{
LogOff();
for (int i = 0; i < 150; i++)
{
if (IsLoggedIn() == true)
{
Thread.Sleep(500);
}
else
{
break;
}
}
}
}
LogOff sends a Cmd command to log off the current session
public static void LogOff()
{
string strCmdIn = "/C LOGOFF " + sessionId + " /SERVER:" + serverName;
Cmd.Exec(strCmdIn);
}
Start() Simply opens Outlook, causing a Citrix session to also start. The app is definitely launching Outlook, but after that it doesn't reach either of the for statements - the BackgroundWorker just exits.
public static void Start()
{
Process.Start(appDataCitrix + "Outlook.exe");
for (int i = 0; i < 15; i++)
{
if (IsLoggedIn2() == false)
{
Thread.Sleep(1000);
}
else
{
break;
}
}
if (IsLoggedIn2() == false)
{
Process.Start(appDataCitrix + "Outlook.exe");
for (int i = 0; i < 10; i++)
{
if (IsLoggedIn2() == false)
{
Thread.Sleep(1000);
}
else
{
break;
}
}
}
}
有人知道这里发生了什么吗?这让我发疯!
非常感谢
更新
The RunWorkerCompleted Method:
As far as my understanding goes, this has no baring on when the process will finish.
public void backgroundReset_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (Session.IsLoggedIn())
{
btnFailFinish.Visible = true;
label10.Text = Session.serverName;
pageControl1.SelectedIndex = 3;
}
else
{
pageControl1.SelectedIndex = 10;
pictureBox2.Visible = false;
textBox1.Text = "Double-click Outlook on your desktop to launch a new session.";
textBox15.Text = "Once you have done this please click Finish.";
pictureBox9.Visible = true;
}
}
这可能是因为 start
方法中抛出了异常。
您可以在该方法周围添加一个 try / catch 块并从 catch 中处理错误,或者如果发生异常则检查 RunWorkerCompleted 方法:
private void RunWorkerCompleted (object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
// handle your exception here
}
}