2015年8月21日 星期五

Tree data structure in C#

elegate void TreeVisitor<T>(T nodeData);

class NTree<T>
{
    private T data;
    private LinkedList<NTree<T>> children;

    public NTree(T data)
    {
         this.data = data;
        children = new LinkedList<NTree<T>>();
    }

    public void AddChild(T data)
    {
        children.AddFirst(new NTree<T>(data));
    }

    public NTree<T> GetChild(int i)
    {
        foreach (NTree<T> n in children)
            if (--i == 0)
                return n;
        return null;
    }

    public void Traverse(NTree<T> node, TreeVisitor<T> visitor)
    {
        visitor(node.data);
        foreach (NTree<T> kid in node.children)
            Traverse(kid, visitor);
    }
}
Simple recursive implementation... < 40 lines of code... You just need to keep a reference to the root of the tree outside of the class, or wrap it in another class, maybe rename to TreeNode??

Yet another tree structure:
public class TreeNode<T> : IEnumerable<TreeNode<T>>
{

    public T Data { get; set; }
    public TreeNode<T> Parent { get; set; }
    public ICollection<TreeNode<T>> Children { get; set; }

    public TreeNode(T data)
    {
        this.Data = data;
        this.Children = new LinkedList<TreeNode<T>>();
    }

    public TreeNode<T> AddChild(T child)
    {
        TreeNode<T> childNode = new TreeNode<T>(child) { Parent = this };
        this.Children.Add(childNode);
        return childNode;
    }

    // other features ...
}
Sample usage:
TreeNode root = new TreeNode("root");
{
    TreeNode node0 = root.AddChild("node0");
    TreeNode node1 = root.AddChild("node1");
    TreeNode node2 = root.AddChild("node2");
    {
        TreeNode node20 = node2.AddChild(null);
        TreeNode node21 = node2.AddChild("node21");
        {
            TreeNode node210 = node21.AddChild("node210");
            TreeNode node211 = node21.AddChild("node211");
        }
    }
    TreeNode node3 = root.AddChild("node3");
    {
        TreeNode node30 = node3.AddChild("node30");
    }
}
BONUS
See fully-fledged tree with:
  • iterator
  • searching
  • Java/C#

refer to:
http://stackoverflow.com/questions/66893/tree-data-structure-in-c-sharp/2012855#2012855

2015年8月20日 星期四

How to configure socket connect timeout

When the Client tries to connect to a disconnected IP address, there is a long timeout over 15 seconds... How can we reduce this timeout? What is the method to configure it?

I solved the problem by using Socket.ConnectAsync Method instead of Socket.Connect Method. After invoking the Socket.ConnectAsync(SocketAsyncEventArgs), start a timer (timer_connection), if time is up, check whether socket connection is connected (if(m_clientSocket.Connected)), if not, pop up timeout error.
private void connect(string ipAdd,string port)
    {
        try
        {
            SocketAsyncEventArgs e=new SocketAsyncEventArgs();


            m_clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            IPAddress ip = IPAddress.Parse(serverIp);
            int iPortNo = System.Convert.ToInt16(serverPort);
            IPEndPoint ipEnd = new IPEndPoint(ip, iPortNo);

            //m_clientSocket.
            e.RemoteEndPoint = ipEnd;
            e.UserToken = m_clientSocket;
            e.Completed+=new EventHandler<SocketAsyncEventArgs>(e_Completed);                
            m_clientSocket.ConnectAsync(e);

            if (timer_connection != null)
            {
                timer_connection.Dispose();
            }
            else
            {
                timer_connection = new Timer();
            }
            timer_connection.Interval = 2000;
            timer_connection.Tick+=new EventHandler(timer_connection_Tick);
            timer_connection.Start();
        }
        catch (SocketException se)
        {
            lb_connectStatus.Text = "Connection Failed";
            MessageBox.Show(se.Message);
        }
    }
private void e_Completed(object sender,SocketAsyncEventArgs e)
    {
        lb_connectStatus.Text = "Connection Established";
        WaitForServerData();
    }
    private void timer_connection_Tick(object sender, EventArgs e)
    {
        if (!m_clientSocket.Connected)
        {
            MessageBox.Show("Connection Timeout");
            //m_clientSocket = null;

            timer_connection.Stop();
        }
    }

The code I'm using to set up a socket connection is as following:
try
{
    m_clientSocket = new Socket(
         AddressFamily.InterNetwork,
         SocketType.Stream,
         ProtocolType.Tcp);

    IPAddress ip = IPAddress.Parse(serverIp);
    int iPortNo = System.Convert.ToInt16(serverPort);
    IPEndPoint ipEnd = new IPEndPoint(ip, iPortNo);

    m_clientSocket.Connect(ipEnd);
    if (m_clientSocket.Connected)
    {
        lb_connectStatus.Text = "Connection Established";
        WaitForServerData();
    }
}
catch (SocketException se)
{
    lb_connectStatus.Text = "Connection Failed";
    MessageBox.Show(se.Message);
}

I found this. Simpler than the accepted answer, and works with .NET v2
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

// Connect using a timeout (5 seconds)

IAsyncResult result = socket.BeginConnect( sIP, iPort, null, null );

bool success = result.AsyncWaitHandle.WaitOne( 5000, true );

if ( !success )
{
            // NOTE, MUST CLOSE THE SOCKET

            socket.Close();
            throw new ApplicationException("Failed to connect server.");
}

// Success
//... 

from:
http://stackoverflow.com/questions/1062035/how-to-configure-socket-connect-timeout


[C#]如何達成全域變數的功能

在撰寫C#程式時,想要宣告全域變數,讓程式中每個類別都可以去存取此變數,直接將變數放到最外層的方式是不行的(VB中毒太深!?),根據larrynung大大所查詢到的,C#中並沒有宣告全域變數的方式
http://msdn.microsoft.com/zh-tw/library/ms173109.aspx#
因此要在C#中使用全域變數,一般都是用屬性或是靜態變數來達成,在小朱大大有在MSDN上的回覆過如何宣告全域變數的問題,以下是個簡單的範例
P.S. 感謝 larrynung 提供意見^^ 並根據其意見修改的文章內容


public class Global
{
    public static int iVars = 0;
}

public class MyForm : Form
{
     private void Button_Click(object sender, EventArgs e)
     {
          MessageBox.Show(Global.iVars.ToString());
     }
}
參考

from:
http://www.dotblogs.com.tw/chou/archive/2009/03/11/7438.aspx