I am using SignalR to do RTM and RT- Call Invitation, I created a HubConnectionServices class stored its obj in a public accessible static variable and use it to send messages. For some reason, my app crashes, or does not navigate, when navigation is called.
public class HubConnectionService
{
public readonly HubConnection hubConnection;
public Page currentPage;
public bool currentPageis;
public HubConnectionService(string token)
{
hubConnection = new HubConnectionBuilder().WithUrl(ApiSettings.HubConnection + "/video", (opts) =>
{
opts.Headers.Add("Authorization", token);
opts.HttpMessageHandlerFactory = (message) =>
{
if (message is HttpClientHandler clientHandler)
{
clientHandler.ServerCertificateCustomValidationCallback +=
(sender, certificate, chain, sslPolicyErrors) => { return true; };
}
return message;
};
}).Build();
}
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum ConnectionResult
{
Connected, Disconnected
}
public async Task<ConnectionResult> ConnectAsync()
{
try
{
await hubConnection.StartAsync();
return ConnectionResult.Connected;
}
catch (Exception problem)
{
Debug.WriteLine(problem.Message);
return ConnectionResult.Disconnected;
}
}
public ConnectionResult AddRecivePoints()
{
try
{
// when disconnected
hubConnection.Closed += async (error) =>
{
GlobalVariables.isConnected = false;
while (hubConnection.State != HubConnectionState.Connected)
{
_ = await ConnectAsync();
}
GlobalVariables.isConnected = true;
};
// receive message
_ = hubConnection.On("ReceiveMessage", (Func<string, HubMessage, Task>)(async (user, message) =>
{
await SwitchCases(message);
}));
return ConnectionResult.Connected;
}
catch (Exception)
{
return ConnectionResult.Disconnected;
}
}
private async Task SwitchCases(HubMessage message)
{
switch (message.Type)
{
case HubMessageType.VideoCallInvitation:
{
if (GlobalVariables.UserIsAvailable)
{
GlobalVariables.UserIsAvailable = false;
await Application.Current.MainPage.Navigation.PushAsync(new ReciviedCall(hubMessage: message));
}
break;
}
case HubMessageType.NormalMessage:
Page cpage = Application.Current.MainPage.Navigation.NavigationStack[Application.Current.MainPage.Navigation.NavigationStack.Count - 1];
bool page = cpage?.GetType().Name == nameof(ChatPrivate);
message.IsNotUserCreated = true;
message.IsUserCreated = false;
bool sender = GlobalVariables.CurrentOpenChatUserEmail == message.Sender;
if (page && sender)
{
GlobalVariables.privateChatMessages.Add(message);
}
else
{
DependencyService.Get<INotification>().CreateNotification(message.Sender,message.Data);
//CrossLocalNotifications.Current.Show(message.Data, message.Sender, 0, DateTime.Now);
}
break;
case HubMessageType.UnKnownError:
break;
case HubMessageType.CallAccepted:
break;
case HubMessageType.CallRejected:
if (Application.Current.MainPage.Navigation.NavigationStack.Count > 1)
{
currentPage = Application.Current.MainPage.Navigation.NavigationStack[Application.Current.MainPage.Navigation.NavigationStack.Count - 1];
currentPageis = currentPage.GetType().Name == nameof(RoomPage);
if (currentPageis)
{
_ = await Application.Current.MainPage.Navigation.PopAsync();
}
}
break;
case HubMessageType.NewUserJoinedCall:
break;
case HubMessageType.UserNotAvailableForVideoCall:
bool isInVideoCallPage = Application.Current.MainPage is RoomPage;
if (isInVideoCallPage)
{
_ = await Application.Current.MainPage.Navigation.PopAsync();
}
GlobalVariables.UserIsAvailable = false;
break;
case HubMessageType.UserNotOnline:
break;
default:
break;
}
}
public async Task Disconnect()
{
await hubConnection.StopAsync();
}
public async Task<string> SendMessage(string toUser, HubMessage msg)
{
try
{
await hubConnection.InvokeAsync("SendChatMessageAsync", msg, toUser);
return "OK";
}
catch (Exception X)
{
return X.Message;
}
}
}
Now when I log in:
try
{
GlobalVariables.connectionService = new HubConnectionService("Bearer " + loginresult.IdentityToken);
ConnectionResult connectionResult = await GlobalVariables.connectionService.ConnectAsync();
// 10 attempts to connect to chat hub
for (int i = 0; i < 10; i++)
{
if (connectionResult == ConnectionResult.Disconnected)
{
await GlobalVariables.connectionService.Disconnect();
connectionResult = await GlobalVariables.connectionService.ConnectAsync();
}
else
{
_ = GlobalVariables.connectionService.AddRecivePoints();
break;
}
}
if (connectionResult == ConnectionResult.Disconnected)
{
await DisplayAlert("Error", "Chat service failed restart is required", "Okay");
}
}
catch (Exception x)
{
await DisplayAlert("Error", x.Message, "Okay");
}
Sending Messages
_ = await GlobalVariables.connectionService.SendMessage(toUser, hubMessage);
The only places where I was able to pinpoint the bug is when I tries to reconnect.
When I call -> Close Call -> then receive call
At both these mentiond flows
case HubMessageType.VideoCallInvitation: block won't execute, but the navigation gets stuck half way with partially black screen. I think its something to do with threads, stuck in these for weeks
Related
Is there any way to convert the Task to a Task async or something similar?
I'm testing code, in short learning to perform different functions of Task type and learn to use its correct operation, however I have not been able to solve this "problem", so I want to ask people who have more knowledge about the Tasks.
Task<bool>.Factory.StartNew(() => {}); -> Task<bool>.Factory.StartNew(async () => {});
Here is a summary of what I want to do
private bool completed = false;
void Tester()
{
completed = false;
int iteration = 0;
var log = new Logger();
log.Log(Logger.Level.Debug, "Starting");
try
{
var theTask = Task<bool>.Factory.StartNew( () =>
{
while (!completed)
{
log.Log(Logger.Level.Debug, "Waiting",1);
iteration++;
Thread.Sleep(400);
if (iteration>20)
{
completed = true;
return true;
}
}
return false;
}).Result;
}
catch (Exception e)
{
log.Log(Logger.Level.Error, e.ToString());
}
finally
{
log.Log(Logger.Level.Info, "Completed");
}
}
You can do it. You can see this video to understand async/await pattern: https://www.youtube.com/watch?v=il9gl8MH17s.
Try this:
class Program
{
static async Task Main(string[] args)
{
bool result = await Tester();
System.Diagnostics.Debug.WriteLine($"result: {result}");
}
private static bool completed = false;
static async Task<bool> Tester()
{
completed = false;
int iteration = 0;
//var log = new Logger();
//log.Log(Logger.Level.Debug, "Starting");
try
{
await Task.Factory.StartNew(() =>
{
while (!completed)
{
//log.Log(Logger.Level.Debug, "Waiting", 1);
iteration++;
System.Diagnostics.Debug.WriteLine($"iteration {iteration}");
Task.Delay(2000);
if (iteration > 20)
{
completed = true;
}
}
});
}
catch (Exception e)
{
//log.Log(Logger.Level.Error, e.ToString());
}
finally
{
//log.Log(Logger.Level.Info, "Completed");
}
return completed;
}
}
Class ParserWorker
The WorkerHTMLFile() method iterates through the list.
The list ListUrlActive contains 4 lines.
The ParsingPage(string source) method sends the sparse page to the SiteParser class.
Class SiteParser
Method Parsing(IHtmlDocument document) after executing break, case "Type_2" : interrupts the execution of the code.
If I understood correctly, then the execution of the code should return to the ParserWorker class, to the WorkerHTMLFile() method in the for loop.
And take the next line of the "ListUrlActive" list, but this does not happen.
The code processes only the first line and terminates the execution of the code on the break case "Type_2"
Question.
How to make that after performing break, case "Type_2" the code continues to work further?
class ParserWorker
{
public void WorkerHTMLFile()
{
for (int i = 0; i <= ListUrlActive.Count; i++)
{
string source = File.ReadAllText(ListUrlActive[i]);
ParsingPage(source);
}
}
public async void ParsingPage(string source)
{
var domParser = new HtmlParser();
IHtmlDocument document = await domParser.ParseAsync(source);
siteParser.Parsing(document);
}
}
public class SiteParser
{
public async void Parsing(IHtmlDocument document)
{
switch (objectParsing)
{
case "Type_1":
/// ...
/// ... Code
/// ...
break;
case "Type_2":
var domParserAnnounc = new HtmlParser();
var htmlBlockAnnounc = document.QuerySelectorAll("div.flexRoot > div.view.main");
foreach (var item in htmlBlockAnnounc)
{
string s = item.OuterHtml;
IHtmlDocument documentCur = await domParserAnnounc.ParseAsync(s);
ParsingPoster(documentCur);
}
break;
}
}
}
public async void ParsingPoster(IHtmlDocument document)
{
try
{
try
{
email = document.QuerySelectorAll("#start_widget > div:nth-child(3) > div.form-line.view-form-line > div.adv-point.view-adv-point > script:nth-child(3)")[0].TextContent.Trim();
email = wordProcessing.FindRegularExpression(email, #"(?<=eval\(unescape\(').*(?='\)\))");
email = wordProcessing.DecodeResult(email);
IHtmlDocument htmlDocumentEmail = await domParser.ParseAsync(email);
var itemsAttr = htmlDocumentEmail.QuerySelectorAll("a");
email = itemsAttr[0].TextContent.Trim();
}
catch (Exception ex)
{
InfoMessageErrorEvent?.Invoke("Поле: 'email'. Error !!!" + ex.Message);
}
}
catch (Exception ex)
{
string s1 = ex.Message;
string s2 = ex.StackTrace;
// throw;
}
}
Update_1
Class ParserWorker
WorkerHTMLFile () method
It was: public void WorkerHTMLFile ()
It became: public async void WorkerHTMLFile ()
Changed the composition of the method.
ParsingPage (string source) method
It was: public async void ParsingPage (string source)
It became: public async Task <IHtmlDocument> ParsingPage (string source)
Changed the composition of the method.
Class SiteParser
Method Parsing (IHtmlDocument document)
It was: public async void Parsing (IHtmlDocument document)
From: public async Task Parsing (IHtmlDocument document)
It was: ParsingPoster (documentCur);
Now: await ParsingPoster (documentCur);
Code
class ParserWorker
{
public async void WorkerHTMLFile()
{
for (int i = 0; i <= ListUrlActive.Count; i++)
{
string source = File.ReadAllText(ListUrlActive[i]);
IHtmlDocument document = await ParsingPage(source);
await siteParser.Parsing(document);
}
}
public async Task<IHtmlDocument> ParsingPage(string source)
{
IHtmlDocument document = null;
try
{
var domParser = new HtmlParser();
IHtmlDocument document = await domParser.ParseAsync(source);
document = await siteParser.Parsing(document);
}
catch (Exception ex)
{
string s = ex.Message;
string s1 = ex.StackTrace;
// throw;
}
return document;
}
}
public class SiteParser
{
public async Task Parsing(IHtmlDocument document)
{
switch (settingOper.objectParsing)
{
case "Type_1":
/// ...
/// ... Code
/// ...
break;
case "Type_2":
var domParserAnnounc = new HtmlParser();
var htmlBlockAnnounc = document.QuerySelectorAll("div.flexRoot > div.view.main");
foreach (var item in htmlBlockAnnounc)
{
string s = item.OuterHtml;
IHtmlDocument documentCur = await domParserAnnounc.ParseAsync(s);
await ParsingPoster(documentCur);
}
break;
}
}
}
public async void ParsingPoster(IHtmlDocument document)
{
try
{
try
{
email = document.QuerySelectorAll("#start_widget > div:nth-child(3) > div.form-line.view-form-line > div.adv-point.view-adv-point > script:nth-child(3)")[0].TextContent.Trim();
email = wordProcessing.FindRegularExpression(email, #"(?<=eval\(unescape\(').*(?='\)\))");
email = wordProcessing.DecodeResult(email);
IHtmlDocument htmlDocumentEmail = await domParser.ParseAsync(email);
var itemsAttr = htmlDocumentEmail.QuerySelectorAll("a");
email = itemsAttr[0].TextContent.Trim();
}
catch (Exception ex)
{
InfoMessageErrorEvent?.Invoke("Поле: 'email'. Error !!!" + ex.Message);
}
//...
// ... Parsing additional fields ...
//...
}
catch (Exception ex)
{
string s1 = ex.Message;
string s2 = ex.StackTrace;
// throw;
}
}
Here is the updated code which can help you :
class ParserWorker
{
public void WorkerHTMLFile()
{
for (int i = 0; i <= ListUrlActive.Count; i++)
{
string source = File.ReadAllText(ListUrlActive[i]);
ParsingPage(source);
}
}
public async void ParsingPage(string source)
{
var domParser = new HtmlParser();
IHtmlDocument document = await domParser.ParseAsync(source);
siteParser.Parsing(document);
}
}
public class SiteParser
{
public async void Parsing(IHtmlDocument document)
{
switch (settingOper.objectParsing)
{
case "Type_1":
/// ...
/// ... Code
/// ...
break;
case "Type_2":
var domParserAnnounc = new HtmlParser();
var htmlBlockAnnounc = document.QuerySelectorAll("div.flexRoot > div.view.main");
foreach (var item in htmlBlockAnnounc)
{
string s = item.OuterHtml;
IHtmlDocument documentCur = await domParserAnnounc.ParseAsync(s);
await ParsingPoster(documentCur);
}
break;
}
}
}
public async void ParsingPoster(IHtmlDocument document)
{
try
{
try
{
settingOper.email = document.QuerySelectorAll("#start_widget > div:nth-child(3) > div.form-line.view-form-line > div.adv-point.view-adv-point > script:nth-child(3)")[0].TextContent.Trim();
if (settingOper.email == null)
{
settingOper.email = document.QuerySelectorAll("div[class='adv-point view-adv-point']>script[type*='text/javascript']")[0].TextContent.Trim();
}
settingOper.email = wordProcessing.FindRegularExpression(settingOper.email, #"(?<=eval\(unescape\(').*(?='\)\))");
settingOper.email = wordProcessing.DecodeResult(settingOper.email);
IHtmlDocument htmlDocumentEmail = await domParser.ParseAsync(settingOper.email);
var itemsAttr = htmlDocumentEmail.QuerySelectorAll("a");
settingOper.email = itemsAttr[0].TextContent.Trim();
}
catch (Exception ex)
{
InfoMessageErrorEvent?.Invoke("Поле: 'email'. Error !!!" + ex.Message);
}
}
catch (Exception ex)
{
string s1 = ex.Message;
string s2 = ex.StackTrace;
// throw;
}
}
I majorly fixed the async and await issue for you at some places.
I'm currently working on a project where I use a serial port with a UWP app.
Sometimes I have the problem that I expect a certain amount of data but when I don't get that amount of data my serial port keeps reading until I cancel it manually.
When I initialize the serialDevice I set the serialDevice.ReadTimeout parameter but that doesn't do anything.
I also tried to bind a cancellationToken to the ReadTimeout parameter but that didn't work either. If I remember correctly it cancelled my method before it even finished...
Is there some way to implement a working timeout?
I use this as my base:
public class ReadWriteAdapter
{
public SemaphoreSlim Semaphore { get; }
private static readonly object LockObject = new object();
private static ReadWriteAdapter _instance;
public static ReadWriteAdapter Current
{
get
{
if (_instance == null)
{
lock (LockObject)
{
if (_instance == null)
{
_instance = new ReadWriteAdapter();
}
}
}
return _instance;
}
}
private ReadWriteAdapter()
{
Semaphore = new SemaphoreSlim(1, 1);
}
private SerialDevice _serialPort;
public CancellationTokenSource ReadCancellationTokenSource;
public CancellationTokenSource WriteCancellationTokenSource;
private object _readCancelLock = new object();
private object _writeCancelLock = new object();
private DataWriter _dataWriter;
private DataReader _dataReader;
public bool IsDeviceInitialized()
{
return _serialPort != null;
}
public async Task<string> Init()
{
try
{
if (_serialPort != null) return "port already configured!";
var aqs = SerialDevice.GetDeviceSelector("COM3");
var devices = await DeviceInformation.FindAllAsync(aqs, null);
if (!devices.Any()) return "no devices found!";
await OpenPort(devices[0].Id);
WriteCancellationTokenSource = new CancellationTokenSource();
ReadCancellationTokenSource = new CancellationTokenSource();
return "found port!";
}
catch (Exception ex)
{
return ex.Message;
}
}
private async Task OpenPort(string deviceId)
{
try
{
_serialPort = await SerialDevice.FromIdAsync(deviceId);
if (_serialPort != null)
{
_serialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
_serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
_serialPort.BaudRate = 19200;
_serialPort.Parity = SerialParity.None;
_serialPort.StopBits = SerialStopBitCount.One;
_serialPort.DataBits = 8;
_serialPort.Handshake = SerialHandshake.None;
_dataWriter = new DataWriter(_serialPort.OutputStream);
_dataReader = new DataReader(_serialPort.InputStream);
}
}
catch (Exception ex)
{
throw ex;
}
}
private async Task<byte[]> ReadAsync(CancellationToken cancellationToken, uint readBufferLength)
{
Task<uint> loadAsyncTask;
var returnArray = new byte[readBufferLength];
lock (_readCancelLock)
{
cancellationToken.ThrowIfCancellationRequested();
_dataReader.InputStreamOptions = InputStreamOptions.Partial;
loadAsyncTask = _dataReader.LoadAsync(readBufferLength).AsTask(cancellationToken);
}
var bytesRead = await loadAsyncTask;
if (bytesRead > 0)
{
_dataReader.ReadBytes(returnArray);
}
return returnArray;
}
public async Task<uint> WriteCommand(string PairedCommand)
{
var commandArray = StringToByteArray(PairedCommand);
uint taskResult = 0;
try
{
if (_serialPort != null)
{
if (_dataWriter == null)
{
_dataWriter = new DataWriter(_serialPort.OutputStream);
taskResult = await WriteAsync(WriteCancellationTokenSource.Token, commandArray);
}
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
_dataWriter.DetachStream();
_dataWriter.Dispose();
_dataWriter = null;
}
return taskResult;
}
public async Task<uint> WriteAsync(CancellationToken cancellationToken, byte[] data)
{
Task<uint> storeAsyncTask;
try
{
lock (_writeCancelLock)
{
cancellationToken.ThrowIfCancellationRequested();
_dataWriter.WriteBytes(data);
storeAsyncTask = _dataWriter.StoreAsync().AsTask(cancellationToken);
}
}
catch (Exception ex)
{
throw ex;
}
return await storeAsyncTask;
}
public async Task<byte[]> Listen(uint bufferLength)
{
var listen = new byte[bufferLength];
try
{
if (_serialPort != null)
{
if (_dataReader == null)
{
_dataReader = new DataReader(_serialPort.InputStream);
}
listen = await ReadAsync(ReadCancellationTokenSource.Token, bufferLength);
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (_dataReader != null)
{
_dataReader.DetachStream();
_dataReader.Dispose();
_dataReader = null;
}
}
return listen;
}
public byte[] StringToByteArray(string str)
{
var enc = new ASCIIEncoding();
return enc.GetBytes(str);
}
public void CancelReadTask()
{
lock (_readCancelLock)
{
if (ReadCancellationTokenSource == null) return;
if (ReadCancellationTokenSource.IsCancellationRequested) return;
ReadCancellationTokenSource.Cancel();
ReadCancellationTokenSource = new CancellationTokenSource();
}
}
private void CancelWriteTask()
{
lock (_writeCancelLock)
{
if (WriteCancellationTokenSource == null) return;
if (WriteCancellationTokenSource.IsCancellationRequested) return;
WriteCancellationTokenSource.Cancel();
WriteCancellationTokenSource = new CancellationTokenSource();
}
}
}
And I call it with a code similar to this (short version):
public class ReadData
{
private ReadBlock readBlock = new ReadBlock();
public async Task<byte[]> ReadParaBlock()
{
await ReadWriteAdapter.Current.Semaphore.WaitAsync();
await ReadWriteAdapter.Current.WriteCommand("getData");
byte[] recievedArray = await ReadWriteAdapter.Current.Listen(100);
ReadWriteAdapter.Current.Semaphore.Release();
return recievedArray;
}
}
The simplest way to solve this issue is using the ReadTimeOut itself, but performing the reading independently of what was received.
Read ReadTimeOut Information in Microsoft WebSite
Definition: If ReadTimeout is set to TimeSpan.FromMilliseconds(ulong.MaxValue) (see TimeSpan), then a read request completes immediately with the bytes that have already been received, even if no bytes have been received.
In other words, this way it will immediately read whatever is in the serial buffer.
So you can implement it this way:
SerialDevice SerialDeviceComm;
Task.Run(async () => { SerialDeviceComm = await SerialDevice.FromIdAsync(_serialConnectionInfo[_indexPort].PortID); }).Wait();
SerialDeviceComm.BaudRate = _baudRate;
SerialDeviceComm.Parity = _parity;
SerialDeviceComm.StopBits = _stopBitCount;
SerialDeviceComm.DataBits = _dataBit;
SerialDeviceComm.Handshake = _serialHandshake;
// This will make that regardless of receiving bytes or not it will read and continue.
SerialDeviceComm.ReadTimeout = TimeSpan.FromMilliseconds(uint.MaxValue); // Secret is here
dataReader = new DataReader(SerialDeviceComm.InputStream)
{
InputStreamOptions = InputStreamOptions.Partial
};
string _tempData = "";
Stopwatch sw = new Stopwatch();
sw.Reset();
sw.Start();
while (sw.ElapsedMilliseconds < timeOut)
{
uint receivedStringSize = 0;
Task.Delay(50).Wait(); // Time to take some bytes
dataReader.InputStreamOptions = InputStreamOptions.Partial;
Task.Run(async () => { receivedStringSize = await dataReader.LoadAsync(200); }).Wait();
_tempData += dataReader.ReadString(receivedStringSize);
}
You can see a example code in my git: GitHub with example
I'm looking for ideas about using delegate with async and await. Is it good or not? I've searched on Google but none of them are similar to mine.
I'm defining a method to change a message status (isRead = true) with SignalR:
enum MessageStatus
{
Failure,
Success
}
delegate Task<MessageStatus> MsgDelegate(string id);
public async Task ChangeMessageStatus(string id)
{
string error = string.Empty;
MsgDelegate msg = async (x) =>
{
try
{
using (var db = new VinaChanelDbContext())
{
var message = db.Messages.SingleOrDefault(m => m.Id == x);
if (message != null)
{
message.IsRead = true;
}
return await db.SaveChangesAsync() > 0 ?
MessageStatus.Success : MessageStatus.Failure;
}
}
catch (Exception e)
{
error = e.Message;
return MessageStatus.Failure;
}
};
switch (await msg(id))
{
case MessageStatus.Success:
Clients.Caller.updateStatus(true);
break;
case MessageStatus.Failure:
Clients.Caller.errorMessage(error);
Clients.Caller.updateStatus(false);
break;
}
}
Is my code weird? Should I use it?
Why use a delegate? What's wrong with:
enum MessageStatus
{
Failure,
Success
}
public async Task ChangeMessageStatus(string id)
{
string error = string.Empty;
var status = MessageStatus.Failure;
try
{
using (var db = new VinaChanelDbContext())
{
var message = db.Messages.SingleOrDefault(m => m.Id == id);
if (message != null)
{
message.IsRead = true;
if (await db.SaveChangesAsync() > 0)
{
status = MessageStatus.Success;
}
}
}
}
catch (Exception e)
{
error = e.Message;
}
switch (status)
{
case MessageStatus.Success:
Clients.Caller.updateStatus(true);
break;
case MessageStatus.Failure:
Clients.Caller.errorMessage(error);
Clients.Caller.updateStatus(false);
break;
}
}
You might want to break that top part out into a private method, but I'm not sure why you would want to make it a delegate...
I have class the --- core of the class skeleton is give below:-
class Pingdom
{
public static string Pingdom(List<Config> configtypes)
{
StringBuilder response = new StringBuilder();
bool status = false;
foreach(var c in configtypes)
{
switch(c.Type)
{
case ConfigTypes.Database:
{
status = PingdomDB(c.ConnectionType);
}
break;
case ConfigTypes.API:
{
status = PingdomAPI(c.Endpoint);
}
break;
}
}
if (status)
return "Ping";
else
return "No Ping";
}
-------------------------------------------------------
.......................................................
}
Now, instead of the class being static I would like for it to be in such way that I can take more of an asynchronous approach in a more robust manner.
Essentially, obtain the list of configurations but process them asynchronously.
How to go about this approach?
class Pingdom {
public static string PingMe(List<Config> configtypes)
{
bool status = true;
List<Task> tasks2 = new List<Task>();
foreach (Config config in configtypes)
{
if (config.Type == ConfigTypes.Database)
{
tasks2.Add(Task.Factory.StartNew(() => { status = status && PingdomDB(config.ConnectionType); }, TaskCreationOptions.LongRunning));
}
else if (config.Type == ConfigTypes.API)
{
tasks2.Add(Task.Factory.StartNew(() => { status = status && PingdomAPI(config.ConnectionType); }, TaskCreationOptions.LongRunning));
}
}
Task.WaitAll(tasks2.ToArray(), System.Threading.Timeout.Infinite);
if (status)
return "Ping";
else
return "No Ping";
}
}