Reputation: 454
I have this code to check if Server is available or not:
public static async Task<bool> PingServer()
{
System.Net.NetworkInformation.Ping p1 = new System.Net.NetworkInformation.Ping();
System.Net.NetworkInformation.PingReply PR = await p1.SendPingAsync("pc2");
// check when the ping is not success
if (PR.Status != System.Net.NetworkInformation.IPStatus.Success)
{
return false;
}
return true;
}
Now, my problem is that SendPingAsync
does not support CancellationTokenSource so how can I cancel the last ping to perform a new one to prevent a lot of pings?
When the server is lost it takes seconds to PingServer()
return a false value.
This is how I call PingServer()
:
var task = await PingServer();
if (task == true)
{
//do some stuff like retrieve a table data from SQL server.
}
Why I use ping? because when I want to get a table from SQL server if the server is disconnected my app enter a breakpoint.
public async static Task<System.Data.Linq.Table<Equipment>> GetEquipmentTable()
{
try
{
DataClassesDataContext dc = new DataClassesDataContext();
// note : i tried so many ways to get table synchronize but it still freeze my UI !
return await Task.Run(() => dc.GetTable<Equipment>());
}
catch
{
return null;
}
}
EDIT : I used ping to reduce chance of entering my app in brake mode by getting a table from database. is there any other way to prevent break mode ? is it best way to ping server before calling dc.GetTable() ?
Upvotes: 1
Views: 1843
Reputation: 3453
The system you depend on might fail, or the connection can go down right after your ping, when you're executing your code.
This is why a retry strategy is a much more robust approach then simply pinging a system before calling it.
Here is how you can implement a retry Cleanest way to write retry logic?
I would go with a retry approach, but if you still want to stay with your design you could
PingServer
from this periodic task and make sure you call Ping.SendAsync
with PingOptions.Timeout
being set, see this overloadPingServer
set some kind of shared state, it could be a static variable, or an implementation of the Registry patternAs you can see, this approach is more complex, but you will prevent "lots of pings" to the system you depend on
Upvotes: 1
Reputation: 247551
Consider
public static async Task<bool> PingServer() {
using (var ping = new System.Net.NetworkInformation.Ping()) {
try {
var maxDelay = TimeSpan.FromSeconds(2); //Adjust as needed
var tokenSource = new CancellationTokenSource(maxDelay);
System.Net.NetworkInformation.PingReply PR = await Task.Run(() =>
ping.SendPingAsync("pc2"), tokenSource.Token);
// check when the ping is not success
if (PR.Status != System.Net.NetworkInformation.IPStatus.Success) {
return false;
}
return true;
} catch {
return false;
}
}
}
Where the ping is done with a cancellation token using Task.Run
; If the ping result returns before the allotted time then all is well.
wrapped the component in a using
to dispose of it when exiting function.
Upvotes: 2
Reputation: 1017
Have you considered using the timeout parameter?
This overload allows you to specify a time-out value for the operation.
If that doesn't suffice and your problem is that the ping call is blocking, you could perform it on a background thread providing this is tightly controlled.
Upvotes: 3