0
<%@ Page Language="c#" Debug="true" %>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.Net" %>

<script language="c#" runat="server">

void BtnCheck_Click(Object sender,EventArgs e) {
try
{
    IPHostEntry GetIPHost = Dns.GetHostByName(Request.QueryString["domain"] + ".org");
    LblValue.Text += "<br>" + Request.QueryString["domain"] + ".org#";
    foreach(IPAddress ip in GetIPHost.AddressList)
    {
        long HostIpaddress = ip.Address;
        LblValue.Text += ip.ToString() + "#";
    }
}
catch(Exception ex){
    LblValue.Text += "<br>" + Request.QueryString["domain"] + ".org#";
    LblValue.Text += "" + ex.Message + "#";
}

}
</script>

<html>
<title>DNS LOOKUP</title>
<head>
</head>
<body OnLoad="BtnCheck_Click" value="Send" runat="server">
<asp:Label id="LblValue" runat="server" />
</body>
</html>

When I try to make a dns lookup, it can take more than 3-4 seconds to get the information. I want to limit its loading time to 1000 milliseconds. If it passes to 1001 milliseconds or more, I want to exit the try block. How can I insert a timer to this code?

G.KISA
  • 95
  • 6
  • Do you want it to execute the `catch` block if it exits the `try` block with the timeout? – Enigmativity Apr 04 '16 at 00:43
  • it is not necessary the catch block's response. i only want to get the information with **GetHostByName()** in 1000 milliseconds, if it cant turn any information then a NULL result is okay – G.KISA Apr 04 '16 at 07:16

2 Answers2

1

I would use Microsoft's Reactive Extensions for this. Just NuGet "Rx-Main". Then you can do this:

string hostName = Request.QueryString["domain"] + ".org";

IObservable<string> getIPAddresses =
    from host in Observable.Start(() => Dns.GetHostByName(hostName))
    select String.Join("#", host.AddressList.Select(ip => ip.Address.ToString()));

IObservable<string> getTimeout =
    from x in Observable.Timer(TimeSpan.FromMilliseconds(1001))
    select ""; // Or Timeout message here

string text = Observable.Amb(getIPAddresses, getTimeout).Wait();

LblValue.Text += "<br>" + hostName + "#";
LblValue.Text += text;

The key to making this work is the Observable.Amb operator which basically tries to run both observables and the first one to produce a value wins. The Wait() then simply turns the IObservable<string> into a string based on the last value produced by the observable and since the observables only produce a single value that's all you get.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • As i said it is my first try with asp.net, sorry if i cant understand your answer, i also copy and paste these codes to my codes above, i got this error; *CS0103: 'Observable' name not valid inside the content* something like that a translation from my language to english THANKS – G.KISA Apr 04 '16 at 07:33
  • @G.KISA - Did you NuGet "Rx-Main"? Once you do that you'll need to add the right namespaces but it should work just fine. – Enigmativity Apr 04 '16 at 11:52
0

You can use the WaitForExit extension method shown in this answer to do this.

Simply wrap your Dns.GetHostByName call into an Action which will assign the result to the GetIPHost variable, and invoke the extension method.

try
{
    IPHostEntry GetIPHost = null;
    var action = new Action(() => GetIPHost = Dns.GetHostByName(Request.QueryString["domain"] + ".org"));
    action.WaitForExit(1000); // this will cancel the method after 1000 milliseconds
    if (GetIPHost != null)
    {
        LblValue.Text += "<br>" + Request.QueryString["domain"] + ".org#";
        foreach (IPAddress ip in GetIPHost.AddressList)
        {
            long HostIpaddress = ip.Address;
            LblValue.Text += ip.ToString() + "#";
        }
    }
}
catch (Exception ex)
{
    LblValue.Text += "<br>" + Request.QueryString["domain"] + ".org#";
    LblValue.Text += "" + ex.Message + "#";
}

The WaitForExit extension method:

public static class ActionExtentions
{
    public static bool WaitForExit(this Action action, int timeout)
    {
        var cts = new CancellationTokenSource();
        var task = Task.Factory.StartNew(action, cts.Token);
        if (Task.WaitAny(new[] { task }, TimeSpan.FromMilliseconds(timeout)) < 0)
        {
            cts.Cancel();
            return false;
        }
        else if (task.Exception != null)
        {
            cts.Cancel();
            throw task.Exception;
        }
        return true;
    }
}
Community
  • 1
  • 1
Will Ray
  • 10,621
  • 3
  • 46
  • 61
  • i eddited my question, wrote all the codes in my .aspx page This is my first try with asp.net, i copy your codes and paste them inside my script tags and get en error on the line *public static bool WaitForExit(this Action action, int timeout)* – G.KISA Apr 04 '16 at 07:25
  • What's the error? You must declare extension methods inside a public static class, so be sure to include the `public static class ActionExtentions` as well. – Will Ray Apr 04 '16 at 13:10