定时器限制其在asp.net中try {} catch {}的加载时间

时间:2016-04-03 22:44:44

标签: c# asp.net

<%@ 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>

当我尝试进行dns查找时,获取信息可能需要3-4秒。我想将其加载时间限制为1000毫秒。如果它传递到1001毫秒或更长时间,我想退出try块。如何在此代码中插入计时器?

2 个答案:

答案 0 :(得分:1)

我会使用微软的Reactive Extensions。只是NuGet“Rx-Main”。然后你可以这样做:

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;

使这项工作的关键是Observable.Amb运算符,它基本上尝试运行两个observable,第一个运行生成值wins。 Wait()然后根据observable生成的最后一个值将IObservable<string>简单地转换为string,因为observable只产生一个你得到的唯一值。

答案 1 :(得分:0)

您可以使用WaitForExit扩展名方法shown in this answer来执行此操作。

只需将Dns.GetHostByName电话打包到Action,即可将结果分配给GetIPHost变量,并调用扩展方法。

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 + "#";
}

WaitForExit扩展方法:

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