flyingnn
flyingnn

Reputation: 61

C# TimerCallback return value error

When I use F11 debug, NetStatus value is true, but when I use F5 debug, NetStatus value is false. Why? How do I fix it?

I don't know what time the _connect value changes. Is this a multi-threading synchronization issue?

namespace conn
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;

    class Program
    {
        static void Main(string[] args)
        {
            wait_conn();
        }

        private static void wait_conn()
        {
            bool NetStatus = false;
            string DataS = "127.0.0.1";

            CheckIpConn conn = new CheckIpConn();
            conn.CheckIp(DataS);

            //Thread.Sleep(3000);
            NetStatus = conn.Connected;

            if (!NetStatus)
                Console.WriteLine(conn.Connected.ToString());

            Console.Read();
        }
    }

    public class CheckIpConn
    {
        private int _port = 135;
        private volatile bool _connect;
        private IPEndPoint _iPEndPoint;
        private TcpClient _client;
        private TimerCallback _timerCallBack;
        private System.Threading.Timer _timer;

        public bool Connected
        {
            get { return _connect; }
        }

        public void CheckIp(string Ip)
        {
            _iPEndPoint = new IPEndPoint(IPAddress.Parse(Ip), _port);
            _timerCallBack = new TimerCallback(CheckConnect);
            _timer = new System.Threading.Timer(_timerCallBack, null, 10, 1000);
            _timer.Dispose();
        }

        public void CheckConnect(object o)
        {
            try
            {
                _client = new TcpClient();
                _client.Connect(_iPEndPoint);
                _connect = true;
                _client.Close();
            }
            catch
            {
                _connect = false;
            }
        }
    }
}

Upvotes: 0

Views: 1006

Answers (2)

ChrisWue
ChrisWue

Reputation: 19020

You create a timer which executes a function on the threadpool - so you don't really have much of a gurantee that when CheckIP returns the timer callback has been exececuted.

Furthermore: Why do you dispose of the timer as soon as you created it? While MSDN states that a callback can occur after dispose because the callback is queued this is certainly a bad style. Also this means that you are only checking once - so you might as well do it synchroneously - especially wait_conn indicates that it should wait until a connection has been established.

Also: TcpClient is disposable so you should do:

using (var client = new TcpClient())
{ 
     client.Connect(_iPEndPoint);
     _connect = true;
     client.Close();
}

There is no point having a member variable in the class if you do not do anything with it anyway.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500923

Your code is extremely unclear - it looks like you're trying to do things asynchronously, but doing so badly. For example, you're creating a Timer and then immediately disposing of it.

When stepping line by line in the debugger, that may work - because the timer may get to fire before the Dispose call... but when you just run the code, you're disposing of the timer before it gets a chance to fire. Additionally, you're using the value of conn.Connected immediately after calling CheckIp - so if the timer did fire, it would probably be after you'd checked the value anyway.

I would strongly advise you to just do the check synchronously. Get that working and then consider an asynchronous approach.

Upvotes: 1

Related Questions