所以我的BW看起来像这样:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if ((worker.CancellationPending == true))
{
e.Cancel = true;
return;
}
else
{
worker.ReportProgress(1);
e.Result = PCIsOnline((string)e.Argument);
}
}
PCIsOnline函数启动Ping.Send。一切正常。 但在某些情况下,我想停止BW(或停止ping)。
我试过这个:
bw.CancelAsync(); - 但这并没有帮助我因为APP将永远不会再回到bw_DoWork停止。所以我有办法停止ping或bw。 所以我可以重新开始。
顺便说一下,这也没有帮助。
bw.CancelAsync();
while (!bw.IsBusy)
{
System.Threading.Thread.Sleep(50);
}
永远满足它的正常循环。我猜它是becoz我睡眠线程,但它是一个主线程我虽然BW线程不应该停止。但它似乎确实如此。我已经看到一个线程,而不是睡眠DoEvents被使用,但我使用WPF,它没有它。而且我真的不想等待ping来完成它的工作。
我已经阅读了很多关于BW的线索以及如何停止但在我的情况下没有一个是有帮助的。当我发送CancelAsync()时,DoWork已经通过了CancellationPending检查并且永远不会返回。
PS:Fisrt time我在TextBox_FocusLost中启动BW甚至。并希望在List_SelectChanged中再次停止并运行它。
增加:
public static bool PCIsOnline(string arg)
{
Ping pingSender = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 2;
try
{
PingReply reply = pingSender.Send(arg, timeout, buffer, options);
if (reply.Status == IPStatus.Success) { return true; }
else { return false; }
}
catch
{
return false;
}
}
ADDED2: 正如之前在评论中所述,而不是使用BW更好地使用SendAsync。 Аnd我的代码现在看起来像这样。但我仍然不明白如何在PCIsOnline函数之外停止SendAsync。
public static void PCIsOnline(string arg)
{
Ping pingSender = new Ping();
pingSender.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);
PingOptions options = new PingOptions();
options.DontFragment = true;
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 2;
pingSender.SendAsync(arg, timeout, buffer, options);
}
private static void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
if (e.Cancelled)
{
Console.WriteLine("Ping canceled.");
}
if (e.Error != null)
{
Console.WriteLine("Ping failed:");
Console.WriteLine(e.Error.ToString());
}
PingReply reply = e.Reply;
HandleReply(reply);
}
所以我仍在寻找一种方法来中断BW并重新启动它或者停止PingAsync的方法。
答案 0 :(得分:0)
问题是你只发送取消给bw。但是你也需要向Ping(SendAsync)发送取消。
向Ping发送取消
Ping.SendAsyncCancel();
bw.CancelAsync();
使用SendAsync:
public static bool PCIsOnline(string arg)
{
Ping pingSender = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 2;
try
{
PingReply reply = pingSender.SendAsync(arg, timeout, buffer, options);
if (reply.Status == IPStatus.Success) { return true; }
else { return false; }
}
catch
{
return false;
}
}
答案 1 :(得分:0)
由于我找不到停止ping的方法,我决定忽略ping结果,如果它不是我需要ATM的那个。 所以我只是将签入添加到 HandleReply ,如果不再需要此ping结果,则发送返回。
private void Name_LostFocus(object sender, System.EventArgs e)
{
var textBox = sender as TextBox;
//No longer Using BW since Ping.SendAsync() does the job
PCIsOnline(textBox.Text);
}
private void Search_SelectChanged(object sender, SelectionChangedEventArgs e)
{
ListBox Search = sender as ListBox;
if (Search.SelectedValue != null)
{
this.OldName.Text = Search.SelectedValue.ToString();
PCIsOnline(this.OldName.Text);
}
}
public void PCIsOnline(string arg)
{
Ping pingSender = new Ping();
//Sending argument to perform check later
pingSender.PingCompleted += (sender1, args) => PingCompletedCallback(sender1, args, arg);
PingOptions options = new PingOptions();
options.DontFragment = true;
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 5;
pbrTest.Visibility = System.Windows.Visibility.Visible;
pingSender.SendAsync(arg, timeout, buffer, options);
}
private void PingCompletedCallback(object sender, PingCompletedEventArgs e, String Current)
{
if (e.Cancelled)
{
HandleReply(null, Current, "Cancelled");
return;
}
if (e.Error != null)
{
HandleReply(null, Current, "Error");
return;
}
PingReply reply = e.Reply;
HandleReply(reply, Current, "");
}
private void HandleReply(PingReply reply, String PC, String msgtype = "")
{
//Ignore old result I only need one that is in OldName textBox
if (PC != this.OldName.Text) { return; }
//Next you should add your result handling
//Happens on a error
if (reply == null)
{
/*do something*/
}
//PC is online
else if (reply.Status == IPStatus.Success)
{
/*do something*/
}
//PC is offline
else
{
/*do something*/
}
}
不是解决问题的最好方法,但这是我能想到的最好方法。