Reputation: 2633
I haven't really played with asyn operations before or multiple threads so this is all new to me. So I was hoping for some guidance
Suppose I have a class something like below
public class pinger
{
// Constructor
public Pinger()
{
do while exit = False;
Uri url = new Uri("www.abhisheksur.com");
string pingurl = string.Format("{0}", url.Host);
string host = pingurl;
bool result = false;
Ping p = new Ping();
try
{
PingReply reply = p.Send(host, 3000);
if (reply.Status == IPStatus.Success)
result = true;
}
catch { }
//wait 2 seconds
loop;
}
}
so I can call this with
Pinger firstone = new Pinger
What I want if for control to then return to the main thread leaving the created instance running and pinging the host every two seconds and updating the result variable, that I can then use a get property when I want to know the status from the main thread.
Can any one suggest some good reading / examples to introduce me to multi threading in c#, using Ping as an example seemed a good easy thing to try this out with :)
Cheers
Aaron
Upvotes: 2
Views: 766
Reputation: 34987
I came up with a Task
based approach where there are 3 code paths interacting - please note that most likely the work will be done with just one thread.
The output of the program shown further below is:
public class Program
{
public static object _o = new object();
public static void Main(string[] args)
{
PingReply pingResult = null;
int i = 0;
Task.Run(async () =>
{
var ii = 0;
//no error handling, example only
//no cancelling, example only
var ping = new System.Net.NetworkInformation.Ping();
while (true)
{
Console.WriteLine($"A: {ii} > {DateTime.Now.TimeOfDay}");
var localPingResult = await ping.SendPingAsync("duckduckgo.com");
Console.WriteLine($"A: {ii} < {DateTime.Now.TimeOfDay}, status: {localPingResult?.Status}");
lock (_o)
{
i = ii;
pingResult = localPingResult;
}
await Task.Delay(1000);
ii++;
}
});
Task.Run(async () =>
{
//no error handling, example only
while (true)
{
await Task.Delay(2000);
lock (_o)
{
Console.WriteLine($"B: Checking at {DateTime.Now.TimeOfDay}, status no {i}: {pingResult?.Status}");
}
}
});
Console.WriteLine("This is the end of Main()");
Console.ReadLine();
}
}
Upvotes: 0
Reputation: 56697
I can outline how the class should look :-)
public class pinger
{
private Uri m_theUri;
private Thread m_pingThread;
private ManualResetEvent m_pingThreadShouldStop;
private volatile bool m_lastPingResult = false;
public Pinger(Uri theUri)
{
m_theUri = theUri;
}
public void Start()
{
if (m_pingThread == null)
{
m_pingThreadShouldStop = new ManualResetEvent(false);
m_pingThread = new Thread(new ParameterizedThreadStart(DoPing));
m_pingThread.Start(m_theUri);
}
}
public void Stop()
{
if (m_pingThread != null)
{
m_pingThreadShouldStop.Set();
m_pingThread.Join();
m_pingThreadShouldStop.Close();
}
}
public void DoPing(object state)
{
Uri myUri = state as Uri;
while (!m_pingThreadShouldStop.WaitOne(50))
{
// Get the result for the ping
...
// Set the property
m_lastPingResult = pingResult;
}
}
public bool LastPingResult
{
get { return m_lastPingResult; }
}
}
What does it do? It is a new class with a Start
and a Stop
method. Start
starts the ping, Stop
stops the ping.
Pinging is done in a separate thread and with every ping, the result property is updated.
Upvotes: 3
Reputation: 23833
I would reccomend the Task Parallel Library (TPL) for this. A great article on using the TPL can be found here.
For other infomation on threading in C# can be found on Joseph Albahari's blog. This should provide all the information you need to get you started.
I hope this helps.
Edit: If you want an example of how to thread the above I will be happy to help.
Upvotes: 3