我有一个WPF应用程序,它将用户的主机名字符串作为参数,调用“ ping”类,并ping主机名10次,然后将结果附加到主要形式。
我的问题是(我假设)它们都在同一线程上运行,而不是每次通过for循环ping主机时都显示,而是冻结UI 10秒钟,然后显示文本正确附加。
如何将此类或方法称为新的异步线程,同时仍允许我访问主UI中的表单控件(文本框,richtextbox)?
在旁注中,我还想将更多信息发送回文本框,例如,在ping途中(像普通ping一样),我不想冻结它。
我对此并不陌生,还没有使用ASYNC进行任何操作,我知道我应该将其添加到按钮中,并通过lambda调用该方法,但是我不确定是否需要更改任何代码,因为当我尝试说它只是说我无法从其他线程访问文本框时。
这是调用方法/类并更改“ ping”按钮为“ stop ping”的代码
private void Button_Click(object sender, RoutedEventArgs e)
{
if ((string)_pingBtn.Content == "Ping")
{
_richtext.Visibility = Visibility.Visible;
pingClass.PingHost(_textBox.Text);
_pingBtn.Content = "Stop Ping";
}
else if ((string)_pingBtn.Content == "Stop Ping")
{
_richtext.Visibility = Visibility.Hidden;
_pingBtn.Content = "Ping";
_richtext.Document.Blocks.Clear();
}
}
}
这是我制作的实际ping类,当被调用10次时,它会将字符串附加回UI上的文本框。 Thread.Sleep显然冻结了整个线程,因为它在同一线程上运行,这就是我遇到的问题。
{
class PingClass
{
public void PingHost(string host)
{
if ((string)UserControlCreate.AppWindow._pingBtn.Content == "Ping")
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
//string to hold our return messge
string returnMessage = string.Empty;
//IPAddress instance for holding the returned host
var address = Dns.GetHostEntry(host).AddressList.First();
//set the ping options, TTL 128
PingOptions pingOptions = new PingOptions(128, true);
//create a new ping instance
Ping ping = new Ping();
//32 byte buffer (create empty)
byte[] buffer = new byte[32];
var HasConnection = NetworkInterface.GetIsNetworkAvailable();
//first make sure we actually have an internet connection
if (HasConnection)
{
try
{
//send the ping 4 times to the host and record the returned data.
//The Send() method expects 3 items:
//1) The IPAddress we are pinging
//2) The timeout value
//3) A buffer (our byte array)
PingReply pingReply = ping.Send(address, 1000, buffer, pingOptions);
//make sure we dont have a null reply
if (!(pingReply == null))
{
switch (pingReply.Status)
{
case IPStatus.Success:
returnMessage = string.Format("Reply from host: bytes={0} Response Time={1}ms ", pingReply.Buffer.Length, pingReply.RoundtripTime);
break;
case IPStatus.TimedOut:
returnMessage = "Connection has timed out...";
break;
default:
returnMessage = string.Format("Ping failed: {0}", pingReply.Status.ToString());
break;
}
}
else
returnMessage = "Connection failed for an unknown reason...";
}
catch (PingException ex)
{
returnMessage = string.Format("Connection Error: {0}", ex.Message);
}
catch (SocketException ex)
{
returnMessage = string.Format("Connection Error: {0}", ex.Message);
}
}
else
returnMessage = "No Internet connection found...";
//return the message
UserControlCreate.AppWindow._richtext.AppendText(returnMessage);
}
}
}
}
}