Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在ASP.NET异步页面上干净地处理异步超时_Android_Asp.net_Asynchronous_Android Asynctask_Iasyncresult - Fatal编程技术网

Android 在ASP.NET异步页面上干净地处理异步超时

Android 在ASP.NET异步页面上干净地处理异步超时,android,asp.net,asynchronous,android-asynctask,iasyncresult,Android,Asp.net,Asynchronous,Android Asynctask,Iasyncresult,据此, 始终调用开始事件处理程序 第二个含义 我真的没有 直到最近才被内化的是 事件的开始事件处理程序 注册的异步任务始终是 调用,即使页面已计时 在ASP.NET开始使用之前退出 开始那项任务 在此场景中,剩余的 任务基本上是注定的。页面 已超时,但ASP.NET正在运行 还是要走过场 调用的开始事件处理程序的 所有已注册的任务,然后 立即打电话给他们的 相应的超时事件处理程序 异步超时并不意味着异步任务取消 在可能的情况下,我应该注意,一旦整个页面超时已经触发,就不要启动其他任务,一旦超时发

据此,

始终调用开始事件处理程序

第二个含义 我真的没有 直到最近才被内化的是 事件的开始事件处理程序 注册的异步任务始终是 调用,即使页面已计时 在ASP.NET开始使用之前退出 开始那项任务

在此场景中,剩余的 任务基本上是注定的。页面 已超时,但ASP.NET正在运行 还是要走过场 调用的开始事件处理程序的 所有已注册的任务,然后 立即打电话给他们的 相应的超时事件处理程序

异步超时并不意味着异步任务取消

在可能的情况下,我应该注意,一旦整个页面超时已经触发,就不要启动其他任务,一旦超时发生,我应该取消其余正在运行的任务。这是推荐的/安全的吗?如果异步任务可能位于多个位置,我将如何彻底取消任何HttpWebRequest.BeginGetResponse调用?例如,如果我在BeginGetResponse调用中,我应该返回什么来让IAsyncResult安全地停止处理?同样的准则是否适用于SqlCommand.BeginExecuteReader

我从几个示例和我自己添加的内容中收集了一个示例代码:

<%@ Page Language="C#" Async="true" AsyncTimeout="30" %>

<%@ Import Namespace="System.Net" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.Threading" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    protected class RequestState
    {
        public HttpWebRequest Request;
        public string RequestID; // simple identifier of the request
        public string Url;
        public DateTime RequestStartTime;

        public RequestState(string requestID, string url)
        {
            this.RequestID = requestID;
            this.Url = url;
        }

        public void CreateRequest()
        {
            Request = (HttpWebRequest)WebRequest.Create(Url + pageDest);
            Request.Method = "GET";
            Request.Proxy = WebRequest.DefaultWebProxy;
            Request.Timeout = 1000 * 3; // Connection timeout
            Request.ReadWriteTimeout = 1000 * 15; // Read response timeout

            RequestStartTime = DateTime.Now; // Technically the request didn't start yet, but this is close enough
        }
    }

    protected class ResponseDetails
    {
        public string RequestID;
        public string Url;
        public string ServerID;
        public double Duration;
        public string ResponseString;

        public string FormattedDuration
        {
            get
            {
                return String.Format("{0:N0}ms", Duration);
            }
        }

        public bool IsServerOk
        {
            get
            {
                // trivial check, better check intended for real implementation
                return ResponseString.Contains("<body");
            }
        }

        public ResponseDetails(RequestState reqState, string serverID, string responseString)
        {
            this.RequestID = reqState.RequestID;
            this.ServerID = serverID;
            this.Url = reqState.Url;
            this.ResponseString = responseString;
            this.Duration = (DateTime.Now - reqState.RequestStartTime).TotalMilliseconds;
        }
    }

    public const string pageDest = "/";
    Dictionary<string, string> serverRequests = new Dictionary<string, string>()
    {
      { "dev1", "http://www.yahoo.com" },
      { "dev2", "http://www.msn.com" },
      { "dev3", "http://www.google.com" }
    };
    Dictionary<string, ResponseDetails> serverResponses = new Dictionary<string, ResponseDetails>();
    object dictLock = new object();
    int maxIOThreads = 0;
    int maxWorkerThreads = 0;

    protected bool ShowThreadingInfo = false;
    protected bool ShowRequestTime = true;
    protected bool ExecuteInParallel = true;

    private string GetThreadingCounts()
    {
        StringBuilder sb = new StringBuilder();

        sb.AppendFormat("<b>EndIOCPUpDate {0}</b><br />", DateTime.Now);
        /*
                sb.AppendFormat("CompletedSynchronously: {0}<br/><br/>" + AR.CompletedSynchronously + "<br /><br />");

                sb.AppendFormat("isThreadPoolThread: " + System.Threading.Thread.CurrentThread.IsThreadPoolThread.ToString() + "<br />";

                sb.AppendFormat("ManagedThreadId : " + System.Threading.Thread.CurrentThread.ManagedThreadId + "<br />";

                sb.AppendFormat("GetCurrentThreadId : " + AppDomain.GetCurrentThreadId() + "<br />";

                sb.AppendFormat("Thread.CurrentContext : " + System.Threading.Thread.CurrentContext.ToString() + "<br />";
        */

        int availWorker = 0;
        int maxWorker = 0;
        int availCPT = 0;
        int maxCPT = 0;

        ThreadPool.GetAvailableThreads(out availWorker, out availCPT);
        ThreadPool.GetMaxThreads(out maxWorker, out maxCPT);

        if (maxIOThreads < (maxCPT - availCPT))
            maxIOThreads = (maxCPT - availCPT);
        if (maxWorkerThreads < (maxWorker - availWorker))
            maxWorkerThreads = (maxWorker - availWorker);

        sb.AppendFormat("--Available Worker Threads: {0}<br/>", availWorker);
        sb.AppendFormat("--Maximum Worker Threads: {0}<br/>", maxWorker);
        sb.AppendFormat("--Available Completion Port Threads: {0}<br/>", availCPT);
        sb.AppendFormat("--Maximum Completion Port Threads: {0}<br/>", maxCPT);
        sb.AppendFormat("===========================<br /><br />");

        return sb.ToString();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        foreach (KeyValuePair<string, string> kvp in serverRequests)
        {
            RequestState reqState = new RequestState(kvp.Key, kvp.Value);

            Page.RegisterAsyncTask(new PageAsyncTask(new BeginEventHandler(this.BeginGetStatusPage),
            new EndEventHandler(this.EndGetStatusPage), new EndEventHandler(this.TimeoutHandler), reqState, ExecuteInParallel));
        }
    }

    protected override void OnPreRenderComplete(EventArgs e)
    {
        base.OnPreRenderComplete(e);
        // write the result messages to the Label.
        MessageOut();
    }

    private IAsyncResult BeginGetStatusPage(Object sender, EventArgs e, AsyncCallback cb, object state)
    {
        RequestState reqState = (RequestState)state;

        AddTraceMessage("Begin " + reqState.Url);

        reqState.CreateRequest();

        return reqState.Request.BeginGetResponse(cb, reqState);
    }

    void EndGetStatusPage(IAsyncResult asyncResult)
    {
        AddTraceMessage("EndAsync");

        if (asyncResult != null)
        {
            RequestState reqState = asyncResult.AsyncState as RequestState;

            AddTraceMessage("End " + reqState.Url);

            string serverKey = null;
            string retString = null;
            StringBuilder sb = new StringBuilder();

            try
            {
                using (WebResponse response1 = (WebResponse)reqState.Request.EndGetResponse(asyncResult))
                {
                    AddTraceMessage("End Response " + reqState.Url);

                    // grab a custom header later, not useful yet
                    serverKey = response1.Headers["Server"];

                    // we will read data via the response stream
                    using (Stream resStream = response1.GetResponseStream())
                    {
                        using (StreamReader rdr = new StreamReader(resStream))
                        {
                            sb.Append(rdr.ReadToEnd());
                            rdr.Close();
                        }
                        resStream.Close();
                    }
                    response1.Close();
                }
            }
            catch (WebException ex)
            {
                sb.AppendLine(ex.Status.ToString() + ": " + ex.Message);
            }
            retString = sb.ToString();

            AddTraceMessage("End Response2 " + reqState.Url);

            ResponseDetails rd = new ResponseDetails(reqState, serverKey, retString);

            UpdateServerResponses(rd);
        }
    }

    void UpdateServerResponses(ResponseDetails details)
    {
        lock (dictLock)
        {
            serverResponses.Add(details.RequestID, details);
        }
    }

    // This doesn't actually cancel the task I don't think
    void TimeoutHandler(IAsyncResult asyncResult)
    {
        AddTraceMessage("Request Timed Out");
        // Aborts one request running during page timeout.  What about the rest??
        RequestState reqState = asyncResult.AsyncState as RequestState;
        reqState.Request.Abort();

        ShowErrorDetails("<span style='color:red;font-weight:bold'>Timed out:</span> " + reqState.RequestID + "<br/><br/>");
    }

    private void ShowErrorDetails(ResponseDetails rd)
    {
        PanelErrors.Visible = true;
        LabelErrors.Text += String.Format("<span style='color:blue;font-weight:bold'>{0}</span><br/>{1}<br/><br/>", rd.RequestID, rd.ResponseString);
    }

    private void ShowErrorDetails(string message)
    {
        PanelErrors.Visible = true;
        LabelErrors.Text += message;
    }
    private void MessageOut()
    {
        PanelThreading.Visible = ShowThreadingInfo;

        Page.Trace.Write(_trace.ToString());

        foreach (KeyValuePair<string, string> kvp in serverRequests)
        {
            string respStr = "<font color='red'>No Reply</font>";

            if (serverResponses.ContainsKey(kvp.Key))
            {
                ResponseDetails rd = serverResponses[kvp.Key];

                if (rd.IsServerOk)
                {
                    respStr = "OK";
                    respStr += " (" + rd.ServerID + ")";
                }
                else
                {
                    ShowErrorDetails(rd);
                    respStr = "<font color='red'>ERROR</font>";
                }

                //In parallel task mode it seems to return the time of the single longest individual request.  Really weird.
                if (ShowRequestTime)
                    respStr += " [" + rd.FormattedDuration + "]";
            }

            this.Label1.Text += String.Format("{0}: {1}<br/>", kvp.Key, respStr);
        }

        this.Label1.Text += String.Format("<br/><b>MaxWorkerThreads:</b> {0}<br/>", maxWorkerThreads);
        this.Label1.Text += String.Format("<b>MaxIOThreads:</b> {0}<br/>", maxIOThreads);
    }

    StringBuilder _trace = new StringBuilder();
    DateTime _pageStartTime = DateTime.Now;

    public void AddTraceMessage(string message)
    {
        double t = (DateTime.Now - _pageStartTime).TotalSeconds;

        lock (_trace)
        {
            _trace.AppendFormat("Thread:[{0:000}] {1:00.000} -- {2}\r\n",

            System.Threading.Thread.CurrentThread.GetHashCode(), t, message);

            LabelThreading.Text += GetThreadingCounts();
        }
    }

</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Label runat="server" ID="Label1"></asp:Label>
        <asp:Panel runat="server" ID="PanelErrors" Visible="false">
            <br />
            <h2>
                Error Details:</h2>
            <br />
            <asp:Label runat="server" ID="LabelErrors"></asp:Label>
        </asp:Panel>
        <asp:Panel runat="server" ID="PanelThreading" Visible="true">
            <br />
            <h2>
                Threading Details:</h2>
            <br />
            <asp:Label runat="server" ID="LabelThreading"></asp:Label>
        </asp:Panel>
    </div>
    </form>
</body>
</html>

受保护类请求状态
{
公共HttpWebRequest请求;
公共字符串RequestID;//请求的简单标识符
公共字符串Url;
公共日期时间请求开始时间;
公共请求状态(字符串请求ID、字符串url)
{
this.RequestID=RequestID;
this.Url=Url;
}
public void CreateRequest()
{
Request=(HttpWebRequest)WebRequest.Create(Url+pageDest);
Request.Method=“GET”;
Request.Proxy=WebRequest.DefaultWebProxy;
Request.Timeout=1000*3;//连接超时
Request.ReadWriteTimeout=1000*15;//读取响应超时
RequestStartTime=DateTime.Now;//从技术上讲,请求尚未启动,但这已经足够接近了
}
}
受保护类响应详细信息
{
公共字符串请求ID;
公共字符串Url;
公共字符串ServerID;
公共双倍期限;
公共开支;
公共字符串格式化持续时间
{
收到
{
返回String.Format(“{0:N0}ms”,持续时间);
}
}
公共图书馆IsServerOk
{
收到
{
//琐碎的检查,更好的检查旨在真正实现

return ResponseString.Contains(“我还应该提供其他信息吗?我的另一个担忧是很少有人使用异步任务,这让我们想知道这在框架内的测试有多好。