おはよう。ここでSendPingAsyncメソッドを停止する方法を教えてください。SendAsyncCancelを試しましたが、スレッドが1つだけ停止するため、すべてのpongスレッドをキャンセルする必要があります。ボタンでPing.SendAsyncを停止WPFをクリック
private void refreshbtn_Click(object sender, EventArgs e)
{
if (tokenSource != null) //check if its even initialized or not
tokenSource.Cancel();
lstNetworks.Items.Clear();
string gate_ip = NetworkGateway();
//Extracting and pinging all other ip's.
string[] array = gate_ip.Split('.');
for (int i = 1; i <= 255; i++)
{
string ping_var = array[0] + "." + array[1] + "." + array[2] + "." + i;
//time in milliseconds
Ping(ping_var, 1, 4000);
}
}
public void Ping(string host, int attempts, int timeout)
{
tokenSource = new CancellationTokenSource();
Task.Factory.StartNew(() =>
{
try
{
System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
ping.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);
ping.SendAsync(host, timeout, host);
}
catch
{
// Do nothing and let it try again until the attempts are exausted.
// Exceptions are thrown for normal ping failurs like address lookup
// failed. For this reason we are supressing errors.
}
}, tokenSource.Token);
}
private void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
// If an error occurred, display the exception to the user.
if (e.Reply.Status == IPStatus.Success)
{
string hostName = GetHostName(e.Reply.Address.ToString());
string macAdress = GetMacAddress(e.Reply.Address.ToString());
if (!Dispatcher.CheckAccess())
{
Dispatcher.Invoke(new Action(() =>
{
lstNetworks.Items.Add(new InfoItem() { IP = e.Reply.Address.ToString(), MAC = macAdress, HOST = hostName });
lstNetworks.Items.SortDescriptions.Add(new SortDescription("IP", ListSortDirection.Ascending));
}));
}
}
else {
//Console.WriteLine(String.Concat("Non-active IP: ", e.Reply.Address.ToString()))
}
}
私がリフレッシュボタンをクリックするたびに、新しいping操作を開始する必要があります。私の場合は、1つのpingスレッドしか停止しませんが、残りは動作し続けます。
UPDATE
あなたが書いたように私は私が再びリフレッシュボタンを押すと、すべてのスレッドが(30秒)を停止するまでの私のアプリがフリーズ、試してみました。しかし、アプリが解凍したときの結果は同じです。前回のSendAsyncのすべてのPingパケットに、2回目の送信した新しいSensAsyncパケットが追加されました。私はスレッドだけでなく、SendAsyncスレッドも停止する必要があります。メソッドSendAsyncCancelがありますが、取り消しトークンが発生したときにどのように呼び出すことができますか?
あなたが書きましたように、私はすべてのスレッドが(30秒)停止するまで、私は再びリフレッシュボタンを押します。しかし、アプリが解凍したときの結果は同じです。前回のSendAsyncのすべてのPingパケットに、2回目の送信した新しいSensAsyncパケットが追加されました。私はスレッドだけでなく、SendAsyncスレッドも停止する必要があります。メソッドSendAsyncCancelがありますが、取り消しトークンが発生したときにどのように呼び出すことができますか? –
更新を参照してください。 UIスレッドをブロックしないようにコードを追加し、SendAsyncCancelの使用方法を追加しました。 –
問題があります。あなたのコードを追加しましたが、コンパイルエラーが発生しました。Task.WaitAll(tasks.ToArray()、tokenSource.Token); - 無効にすることはできません –