I am building a game in xamarin in which I am trying to show a DisplayAlert Popup when the game is finished (after 8 seconds). However as the time gets to zero it wont show.
If i put the DisplayAlert at the beginning of the time it works fine.
Can you please explain, why this is the case?
The DisplayAlert line is located in the "OnTimedEvent" Method at the end of the code in this ViewModel:
using System;
using System.Diagnostics;
using System.Timers;
using CBTGAME1.Models;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace CBTGAME1.ViewModels
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class GamePageViewModel : ObservableObject
{
Animals aninames = new Animals();
Timer timer;
private int countSecond;
public int CountSecond
{
get { return countSecond; }
set
{
countSecond = value;
OnPropertyChanged(nameof(CountSecond));
}
}
private string nowanimal = null;
public string Nowanimal
{
get { return nowanimal; }
set {
nowanimal = value;
OnPropertyChanged(nameof(Nowanimal));
}
}
public Command Generate { get; }
public Command button1 { get; }
public Command button2 { get; }
public Command button3 { get; }
private int yourscore = 0;
public int Yourscore
{
get { return yourscore; }
set { yourscore = value;
OnPropertyChanged(nameof(Yourscore));
}
}
private string firstb;
private string secondb;
private string thirdb;
public string Firstb
{
get { return firstb; }
set
{
firstb = value;
OnPropertyChanged(nameof(Firstb));
}
}
public string Secondb
{
get { return secondb; }
set
{
secondb = value;
OnPropertyChanged(nameof(Secondb));
}
}
public string Thirdb
{
get { return thirdb; }
set
{
thirdb = value;
OnPropertyChanged(nameof(Thirdb));
}
}
public GamePageViewModel()
{
RndAll();
timer = new Timer();
settimer();
button1 = new Command(() =>
{BtnOperation(firstb); });
button2 = new Command(() =>
{BtnOperation(secondb); });
button3 = new Command(() =>
{BtnOperation(thirdb); });
}
public void BtnOperation(string btname)
{
if (btname == Nowanimal)
Yourscore = Yourscore + 1;
else Yourscore = Yourscore - 1;
RndAll();
}
public void RndAll()
{
Random rnd = new Random();
Nowanimal = aninames.Animalss[rnd.Next(0, 3)];
int i = rnd.Next(0, 3);
Firstb = aninames.Animalss[i];
if (i == 2) i = 0;
else i++;
Secondb = aninames.Animalss[i];
if (i == 2) i = 0;
else i++;
Thirdb = aninames.Animalss[i];
}
public void settimer()
{
CountSecond = 8;
timer.Interval = 1000;
timer.Elapsed += OnTimedEvent;
timer.Enabled = true;
}
private void OnTimedEvent(object sender, ElapsedEventArgs e)
{
CountSecond--;
if (CountSecond == 0)
{
timer.Stop();
App.Current.MainPage.DisplayAlert("finished", "have a good day", "Exit");
}
}
}
}
1) DisplayAlert returns a Task, so await it
2) Call it on the main/ui thread
Device.BeginInvokeOnMainThread (async() => {
await App.Current.MainPage.DisplayAlert("finished", "have a good day", "Exit");
});
Related
I want to create a C# Windows Form application where there is a flow layout panel, filled with User Control elements. Every time I click an element, the some labels must show its attributes. However, the click event doesn't register. I added some breakpoints on the show_preview() method and it never calls the method. The Load event is calling show_preview but I want to do change the labels acordinging to a User Control being clicked.
This is the Form:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
load_plots();
}
private void load_plots()
{
ArrayList items = new ArrayList();
for (int i = 0;i<100;i++)
{
PlotItem plot = new PlotItem();
plot.Place = "Ilion";
plot.Price = i * 1000;
plot.Space = i * 10;
plot.Title = "Plot No." + i;
plot.Width = flowLayoutPanel1.Width - 30;
plot.Click += new EventHandler(this.show_preview);
items.Add(plot);
flowLayoutPanel1.Controls.Add(plot);
}
}
private void show_preview(object sender, EventArgs e)
{
PlotItem clicked = sender as PlotItem;
plot_title.Text = "Hello";
plot_size.Text = clicked.Space.ToString();
plot_value.Text = clicked.Price.ToString();
}
This is the Plot Item:
public partial class PlotItem : UserControl
{
public PlotItem()
{
InitializeComponent();
}
#region Properties
[Category("Plot Object")]
private String _place;
public String Place
{
get { return _place; }
set { _place = value; }
}
[Category("Plot Object")]
private double _price;
public double Price
{
get { return _price; }
set { _price = value; label_price.Text = value.ToString() + "€"; }
}
[Category("Plot Object")]
private String _use;
public String Use
{
get { return _use; }
set { _use = value; }
}
[Category("Plot Object")]
private double _space;
public double Space
{
get { return _space; }
set { _space = value; label_size.Text = value.ToString() + "m2"; }
}
[Category("Plot Object")]
private String _title;
public String Title
{
get { return _title; }
set { _title = value; label_title.Text = value; }
}
[Category("Plot Object")]
private Image _icon;
public Image Icon
{
get { return _icon; }
set { _icon = value; plot_preview.Image = value; }
}
#endregion
private void panel1_MouseEnter(object sender, EventArgs e)
{
this.BackColor = Color.Silver;
}
private void panel1_MouseLeave(object sender, EventArgs e)
{
this.BackColor = System.Drawing.SystemColors.Control;
}
Thanks for your time.
I'm new to blazor C# and trying to make a simple countdown timer website. My website consist of:
Text to display the timer
Start and stop button
Buttons to set the timer
I'm having a problem in the buttons to set the timer. When i click on it, it won't set the timer display and i got an error Argument 2: cannot convert from 'void' to 'Microsoft.AspNetCore.Components.EventCallback'. I search on Youtube for the EventCallback topic but the problem is, my component is not seperated while in the video the example code got seperated components linked together. Here's the code.
Index.razor
#page "/"
#inherits FrontEnd.Components.Timer
<h1>Timer</h1>
<p class="timer">#Hours.ToString("00"):#Minutes.ToString("00"):#Seconds.ToString("00")</p>
#foreach (var timer in timerCollections)
{
// Here's the problem
<button #onclick="SetTimer(timer.Id)">#timer.Hours.ToString("00"):#timer.Minutes.ToString("00"):#timer.Seconds.ToString("00")</button>
}
<br/>
<button #onclick="StartTimer" disabled=#StartButtonIsDisabled>Start</button>
<button #onclick="StopTimer" disabled=#StopButtonIsDisabled>Stop</button>
Timer.cs
using System;
using System.Timers;
using System.Collections.Generic;
using Microsoft.AspNetCore.Components;
namespace FrontEnd.Components
{
public class TimerStructure
{
public int Id { get; set; }
public int Hours { get; set; }
public int Minutes { get; set; }
public int Seconds { get; set; }
}
public class Timer : ComponentBase
{
public List<TimerStructure> timerCollections = new List<TimerStructure>(){
new TimerStructure(){ Id = 1, Hours = 0, Minutes = 30, Seconds = 0 },
new TimerStructure(){ Id = 2, Hours = 1, Minutes = 0, Seconds = 0 }
};
public int Index { get; private set; }
public int Hours { get; set; } = 0;
public int Minutes { get; set; } = 0;
public int Seconds { get; set; } = 0;
public bool StopButtonIsDisabled { get; set; } = true;
public bool StartButtonIsDisabled { get; set; } = false;
private static System.Timers.Timer aTimer;
// and this is the function related to the problem
public void SetTimer(int value)
{
this.Index = value - 1;
Hours = timerCollections[Index].Hours;
Minutes = timerCollections[Index].Minutes;
Seconds = timerCollections[Index].Seconds;
}
public void StopTimer()
{
aTimer.Stop();
aTimer.Dispose();
StopButtonIsDisabled = true;
StartButtonIsDisabled = false;
Console.WriteLine($"{Hours}:{Minutes}:{Seconds}");
}
public void StartTimer()
{
aTimer = new System.Timers.Timer(1000);
aTimer.Elapsed += CountDownTimer;
aTimer.Start();
StopButtonIsDisabled = false;
StartButtonIsDisabled = true;
}
public void CountDownTimer(Object source, ElapsedEventArgs e)
{
if(Seconds == 0 && Minutes > 0)
{
Minutes -= 1;
Seconds = 59;
} else if (Minutes == 0 && Seconds == 0 && Hours > 0)
{
Hours -= 1;
Minutes = 59;
Seconds = 59;
} else if (Hours == 0 && Minutes == 0 && Seconds == 0)
{
aTimer.Stop();
aTimer.Dispose();
StopButtonIsDisabled = true;
StartButtonIsDisabled = false;
} else
{
Seconds -= 1;
}
InvokeAsync(StateHasChanged);
}
}
}
Try: <button #onclick="() => SetTimer(timer.Id)">
I have a small winforms program for a task which is to create a Recipe book. The application has two windows, but my bug pertains to only one.
I have two main classes: Recipe.cs and RecipeManager.cs, the idea is that the RecipeManager holds an array of Recipes. (For this task we weren't allowed to use Linq or ArrayLists)
Now, when I fill in the form and click "Add Recipe", the first one works successfully and the listBox populates correctly, however the second time I "Add Recipe" the recipeList array seems to get rewritten with the new Recipe entirely, and I have no idea why this is happening. The recipeList seems to change before my Add method even adds it to the array!
See gif of problem in question:
https://i.imgur.com/sIMICcG.gifv
Recipe.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace programmingTask4
{
public class Recipe
{
private string[] ingredientArray;
private string name;
private FoodCategory category;
private string description;
private const int maxNumOfIngredients = 20;
public string Name
{
get { return name; }
set { name = value; }
}
public FoodCategory Category
{
get { return category; }
set { category = value; }
}
public string Description
{
get { return description; }
set { description = value; }
}
public string[] Ingredient
{
get { return ingredientArray; }
set { ingredientArray = value; }
}
public int MaxNumOfIngredients
{
get { return ingredientArray.Length; }
}
public Recipe(int maxNumOfIngredients)
{
Console.WriteLine("Recipe constructor was called!");
ingredientArray = new string[maxNumOfIngredients];
DefaultValues();
}
public void DefaultValues()
{
for (int i = 0; i < ingredientArray.Length; i++)
{
ingredientArray[i] = string.Empty;
name = string.Empty;
category = FoodCategory.Vegetarian;
description = string.Empty;
}
}
public int FindVacantPosition()
{
int results;
for (int i = 0; i < ingredientArray.Length; i++)
{
if(ingredientArray[i] == string.Empty)
{
results = i;
return results;
}
}
return -1;
}
public bool AddIngredient(string value)
{
bool ok;
int next = FindVacantPosition();
if(next >= 0)
{
ok = true;
ingredientArray[next] = value;
}
else {
ok = false ;
}
return ok;
}
public bool CheckIndex(int index)
{
bool check = false;
if(index <= ingredientArray.Length && index >= 0)
{
check = true;
}
return check;
}
public int GetCurrentNumOfIngredients()
{
int count = 0;
for (int i = 0; i < ingredientArray.Length; i++)
{
if (!string.IsNullOrEmpty(ingredientArray[i]))
{
count++;
}
}
return count;
}
public override string ToString()
{
int chars = Math.Min(description.Length, 15);
string descriptionText = description.Substring(0, chars);
if (string.IsNullOrEmpty(descriptionText))
descriptionText = "NO DESCRIPTION";
string textOut = string.Format("{0, -20} {1,4} {2,-12} {3,-15}", name, GetCurrentNumOfIngredients(), category.ToString(), descriptionText);
return textOut;
}
public bool ChangeIngredientAt(int index, string value)
{
bool bok = true;
if (CheckIndex(index))
ingredientArray[index] = value;
else
bok = false;
return bok;
}
public bool DeleteIngredientAt(int index)
{
bool bok = true;
if (CheckIndex(index))
ingredientArray[index] = "NO DESCRIPTION";
else
bok = false;
return bok;
}
}
}
RecipeManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace programmingTask1
{
class RecipeManager
{
private Recipe[] recipeList;
public RecipeManager(int maxNumOfElements)
{
Console.WriteLine("Recipe manager constructor called!");
recipeList = new Recipe[maxNumOfElements];
}
private int FindVacantPosition()
{
for (int i = 0; i < recipeList.Length; i++)
{
if (recipeList[i] == null)
{
Console.WriteLine("Found free position at: " + i);
return i;
}
}
return -1;
}
public bool CheckIndex(int index)
{
bool check = false;
if (index <= recipeList.Length && index >= 0)
{
check = true;
}
return check;
}
public Recipe GetRecipeAt(int index)
{
if (CheckIndex(index))
return recipeList[index];
else
return null;
}
public bool Add(Recipe newRecipe)
{
if (newRecipe == null)
return false;
bool ok;
int next = FindVacantPosition();
if (next >= 0)
{
ok = true;
Console.WriteLine("Setting recipe list at index " + next + " to " + newRecipe.ToString());
recipeList[next] = newRecipe;
}
else
{
Console.WriteLine("No space for recipe available! " + next);
ok = false;
}
return ok;
}
public int CurrentNumberofItems()
{
int num = 0;
for (int i = 0; i < recipeList.Length; i++)
{
if (recipeList[i] != null)
{
num++;
}
}
return num;
}
public string[] RecipeListToString()
{
string[] results = new string[recipeList.Length];
for (int i = 0; i < recipeList.Length; i++)
{
if (recipeList[i] != null)
results[i] = recipeList[i].ToString();
else
results[i] = string.Empty;
}
return results;
}
}
}
FormMain.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace programmingTask4
{
public partial class FormMain : Form
{
const int maxRecipe = 3;
const int maxIngredients = 20;
Recipe currRecipe = new Recipe(maxIngredients);
RecipeManager recipemanager = new RecipeManager(maxRecipe);
public FormMain()
{
Console.WriteLine("Form constructor was called!");
InitializeComponent();
InitializeGui();
}
public void InitializeGui()
{
comboBoxCategory.DataSource = Enum.GetValues(typeof(FoodCategory));
}
public void UpdateGUI()
{
//listBoxDisplay.Text = recipemanager.CurrentNumberofItems().ToString();
//listBoxDisplay.Text = currRecipe.Ingredient.ToString();
string[] recipeListStrings = recipemanager.RecipeListToString();
listBoxDisplay.Items.Clear();
listBoxDisplay.Items.AddRange(recipeListStrings);
}
private void buttonRecipe_Click(object sender, EventArgs e)//add recipe button
{
currRecipe.Category = (FoodCategory)comboBoxCategory.SelectedIndex;
currRecipe.Name = textBoxRecipeName.Text.Trim();
currRecipe.Description = richTextBoxDescription.Text.Trim();
Console.WriteLine("Adding recipe: " + currRecipe.ToString());
bool result = recipemanager.Add(currRecipe);
Console.WriteLine("Result was " + result + " for adding to recipe list");
UpdateGUI();
currRecipe.DefaultValues();
}
}
}
Recipe is a class, which mean it's a reference type.
In your main form, your currRecipe instance is never changed.
RecipeManager has an array to store references of instance but unfortunately it stores the same instance because of 2.
Since RecipeManager stores the same instance of currRecipe, any modification on currRecipe would display N times.
To prevent it. Modify your buttonRecipe_Click
private void buttonRecipe_Click(object sender, EventArgs e)//add recipe button
{
currRecipt = new Recipe(maxIngredients);
currRecipe.Category = (FoodCategory)comboBoxCategory.SelectedIndex;
currRecipe.Name = textBoxRecipeName.Text.Trim();
currRecipe.Description = richTextBoxDescription.Text.Trim();
Console.WriteLine("Adding recipe: " + currRecipe.ToString());
bool result = recipemanager.Add(currRecipe);
Console.WriteLine("Result was " + result + " for adding to recipe list");
UpdateGUI();
// No need to reset it, use new one everytime.
//currRecipe.DefaultValues();
}
I have a function, which takes a long time.
When the function is running, I would like to show some pictures, but this code doesn't work. Why ?
(I must use only framework 4)
This is the code XAML
<Image Width="33" Stretch="Uniform" Source="{Binding ImagePath, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Grid.Column="0"/>
This is the code
public bool Cmd_TestExe()
{
Thread trd_A = new Thread(MyThreadTask_ShowImg);
Thread_Status = false;
trd_A.Start();
if (My_Slow_Function(sCon) == false) {
displayMessage(Status_Failure);}
}
public void Wait(int sleep)
{
dynamic dFrame = new DispatcherFrame();
ThreadPool.QueueUserWorkItem(state =>
{
Thread.Sleep(sleep);
dFrame.Continue = false;
});
Dispatcher.PushFrame(dFrame);
}
public void MyThreadTask_ShowImg()
{
while (Thread_Status == false) {
Application.Current.Dispatcher.Invoke(new Action(() =>
{
if (Second(Now) % (2) == 0) {
ImagePath = "/Images/exit.png";
Wait(250);
} else {
ImagePath = "/Images/excel.png";
Wait(250);
Console.WriteLine(Now);
}
}));
}
}
...and this is the property
private string _ImagePath { get; set; }
public string ImagePath {
get { return _ImagePath; }
set {
_ImagePath = value;
OnPropertyChanged("ImagePath");
}
}
First, you have to return a bool in your Cmd_TestExe Method.
Second, I've never use DispatcherFrame, but this is how I would do :
public partial class MainWindow : Window
{
Thread myLittleThread;
bool stop;
public string ImageSource
{
set
{
myLittleImage.Source = new BitmapImage(new Uri(value));
}
}
public MainWindow()
{
InitializeComponent();
InitThread();
}
private void InitThread()
{
myLittleThread = new Thread(DoWork);
stop = false;
Application.Current.Exit += MyLittleApplication_Exit;
myLittleThread.Start();
}
private void MyLittleApplication_Exit(object sender,EventArgs e)
{
stop = true;
}
private void DoWork(){
string newImageSource;
while (!stop)
{
if (DateTime.Now.Second % 2 == 0)
{
newImageSource = "SomeRandomFooImage.png";
}
else
{
newImageSource = "MyLittleRandomImage.png";
}
Application.Current.Dispatcher.Invoke(new Action(() =>
{
ImageSource = newImageSource;
}));
Thread.Sleep(250);
}
}
}
and XAML :
<Image Name="myLittleImage" ></Image>
I'm working on a network monitoring application, that pings a (not known) number of hosts. So far I have the code below. I've made a class PingHost with a function zping and I called it with the help of a timer once every 2 seconds to let the 2 pings to finish, even if one of them gets TimedOut. But I think a better solution is to generate a new thread for every ping, so that the ping of every host would be independent.
Can anyone give me a hint how to do this?
namespace pinguin
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
PingHost caca = new PingHost();
PingHost caca1 = new PingHost();
this.label1.Text = caca.zping("89.115.14.160");
this.label2.Text = caca1.zping("89.115.14.129");
}
}
public class PingHost
{
public string zping(string dest)
{
Application.DoEvents();
Ping sender = new Ping();
PingOptions options = new PingOptions();
options.DontFragment = true;
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
int timeout = 50;
int failed = 0;
int pingAmount = 5;
string stat = "";
PingReply reply = sender.Send(dest, timeout, buffer, options);
if (reply.Status == IPStatus.Success)
{
stat = "ok";
}
else
{
stat = "not ok!";
}
return stat;
}
}
}
If you use .NET 4 you can use Parallel.Invoke.
You could handle the Ping.PingCompleted event:
ping.PingCompleted += new PingCompletedEventHandler(ping_PingCompleted);
then use:
ping.SendAsync()
side note: Choose more suitable names for your classes and routines. PingHost is more suitable as a routine name
Once I wrote such a solution (it constantly pings about 300 machines):
public class ManyAdressPing {
private readonly bool bAutoStarted;
private readonly CancellationTokenSource cancel = new CancellationTokenSource();
public ConcurrentDictionary<IPAddress, OneAddressPing> pingi = new ConcurrentDictionary<IPAddress, OneAddressPing>();
public ManyAdressPing(bool AutoStarted = true) {
bAutoStarted = AutoStarted;
}
public int CountPings => pingi.Count;
public void AddPingAddress(IPAddress addr, int msTimeOut = 3000, int BetweenPing = 3000) {
var oap = new OneAddressPing(addr, cancel.Token, msTimeOut, BetweenPing);
if (bAutoStarted) oap.Start();
pingi.TryAdd(oap.ipAddress, oap);
}
public void RemovePingAddress(IPAddress addr) {
if (pingi.TryRemove(addr, out var p)) p.Stop();
}
public void Stop() {
cancel.Cancel();
foreach (var pair in pingi) pair.Value.Stop();
}
public PingReply GetReply(IPAddress addr) {
if (pingi.ContainsKey(addr)) return pingi[addr].GetReply();
return null;
}
public Tuple<long, long> GetSuccessOperation(IPAddress addr) {
if (pingi.ContainsKey(addr)) return pingi[addr].GetSuccessOperation();
return null;
}
public PingReply[] GetReply() {
PingReply[] ret = pingi.Values.Select(x=>x.GetReply()).ToArray();
return ret;
}
public PingInfo GetPingInfo(IPAddress addr) {
if (pingi.ContainsKey(addr)) {
var ret = new PingInfo();
var p = pingi[addr];
ret.reply = p.GetReply();
ret.SuccessPing = p._SuccessReply;
ret.FailPing = p._FailReply;
ret.LastSuccessPing = p.LastSuccessfullPing;
return ret;
}
return null;
}
public bool IsPinged(IPAddress addr) {
if (pingi.ContainsKey(addr)) return true;
return false;
}
public IPAddress[] GetAddressesPing() {
return pingi.Keys.ToArray();
}
}
public class PingInfo {
public PingReply reply;
public long SuccessPing = 0;
public long FailPing = 0;
public DateTime LastSuccessPing;
public override string ToString() {
return $"Sping: {SuccessPing} last={LastSuccessPing}, Fping:{FailPing}, reply:{reply}";
}
}
public class OneAddressPing {
public static byte[] bu = {
0
};
public long _FailReply;
public long _SuccessReply;
private bool bStop = false;
private readonly CancellationToken cancellationToken;
public DateTime LastSuccessfullPing = DateTime.MinValue;
public int mSecBetweenPing = 3000;
public Ping ping;
public PingOptions popt;
private Task pTask;
// Here is a self-written LIFO stack
public LightQueue<PingReply> replys = new LightQueue<PingReply>(10);
private readonly AutoResetEvent reset = new AutoResetEvent(false);
private Logger log = null;
private Task pinging = null;
public OneAddressPing(IPAddress addr, CancellationToken ct, int timeOut = 3000, int BetweenPing = 3000, Logger _log =null) {
ipAddress = addr;
popt = new PingOptions();
popt.DontFragment = false;
cancellationToken = ct;
mSecTimeOut = timeOut;
mSecBetweenPing = BetweenPing;
log = _log;
}
public int mSecTimeOut { get; set; } = 3000;
public IPAddress ipAddress { get; set; }
public int CountPings => replys.Length;
private void SetReply(PingReply rep) {
if (rep == null) return;
replys.Put(rep);
if (rep.Status == IPStatus.Success) {
Interlocked.Increment(ref _SuccessReply);
LastSuccessfullPing = DateTime.Now;
} else {
Interlocked.Increment(ref _FailReply);
}
}
public async Task Start() {
if (pTask == null || pTask.Status != TaskStatus.Running) {
ping = new Ping();
Task.Factory.StartNew(PingCircle, TaskCreationOptions.RunContinuationsAsynchronously | TaskCreationOptions.LongRunning); pTask = Task.Run(PingCircle, cancellationToken);
}
}
public void Stop() {
if (pTask.Status == TaskStatus.Running) {
bStop = true;
try {
pTask.Wait(mSecTimeOut, cancellationToken);
} catch (Exception ex) {
log.ErrorSource($"Error ping stop: {ex.Message}");
}
}
}
private async Task PingCircle() {
while (cancellationToken.IsCancellationRequested == false && !bStop) {
try {
try {
PingReply rep = await ping.SendPingAsync(ipAddress, mSecTimeOut, bu,popt);
if (rep != null) SetReply(rep);
} catch (PingException p) {
// ignore ping error
Debug.WriteLine($"error: {p}");
} catch (Exception ee) {
log?.ErrorSource(ee);
Debug.WriteLine($"error: {ee}");
}
await Task.Delay(mSecBetweenPing, cancellationToken);
} catch (Exception ee) {
log?.ErrorSource(ee);
}
}
}
public PingReply GetReply() {
if (replys.IsEmpty) return null;
return replys.PeekLast(0);
}
public Tuple<long, long> GetSuccessOperation() {
return new Tuple<long, long>(_SuccessReply, _FailReply);
}
public bool LongPingSuccess() {
int ret = 0;
for (int i = 0; i < 5; i++) {
var r = replys.PeekLast(i);
if (r.Status == IPStatus.Success) ret++;
}
if (ret > 2) return true;
return false;
}
}