c # асинхронный объект - PullRequest
2 голосов
/ 23 марта 2012

Я до сих пор не играл с асинхронными операциями или несколькими потоками, так что это все для меня в новинку.Так что я надеялся на какое-то руководство

Предположим, у меня есть класс, подобный приведенному ниже

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;
    }


}

, поэтому я могу вызвать его с помощью

Pinger firstone = new Pinger

Что я хочу, если дляуправляйте, чтобы затем возвращаться к основному потоку, оставляя созданный экземпляр запущенным и проверяя хост каждые две секунды и обновляя переменную результата, чтобы затем я мог использовать свойство get, когда хочу узнать состояние из основного потока.

Может ли кто-нибудь предложить несколько хороших чтений / примеров, чтобы познакомить меня с многопоточностью в c #, используя Ping в качестве примера, показалось довольно легкой вещью, чтобы попробовать это с :)

Cheers

Аарон

Ответы [ 3 ]

3 голосов
/ 23 марта 2012

Я могу обрисовать, как должен выглядеть класс: -)

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; }
    }
}

Что он делает?Это новый класс с Start и Stop методом.Start запускает пинг, Stop останавливает пинг.

Пинг выполняется в отдельном потоке, и при каждом пинге свойство результата обновляется.

3 голосов
/ 23 марта 2012

Я бы порекомендовал для этого параллельную библиотеку задач (TPL). Отличная статья об использовании TPL может быть найдена здесь .

Дополнительную информацию о потоках в C # можно найти в блоге Джозефа Албахари . Это должно предоставить всю информацию, необходимую для начала работы.

Надеюсь, это поможет.

Редактировать: Если вам нужен пример того, как продвигать нить выше, я буду рад помочь.

0 голосов
/ 22 декабря 2016

Я предложил подход, основанный на Task, в котором взаимодействуют 3 пути кода - обратите внимание, что, скорее всего, работа будет выполняться только с одним потоком.

Вывод программы, показанной ниже:

enter image description here

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();
    }
}
...