是否有任何优雅的方式异步调用网页,忽略响应并释放线程资源

时间:2016-03-30 02:16:22

标签: c# asp.net multithreading asynchronous

我在 ASP.NET 中有一个案例,当请求到达时,一个网页(将其命名为service.aspx)将被异步调用,我不会这样做关心service.aspx的回应,我只需要打电话。

现在,我有两种方法。 第一个是HttpWebRequest.BeginGetResponse,参数回调设置为null。似乎它不是一个好主意,没有办法调用EndGetResponse,所以可能无法释放调用service.aspx线程的资源。 第二个是WebClient.OpenReadAsync,但如果我没有指定OpenReadCompleted事件,我不确定它是否可以释放线程资源。

或许还有其他合适的方式来获得我想要的东西。

2 个答案:

答案 0 :(得分:1)

您可以创建一个将在后台发出Web请求的类。在应用程序的HttpApplication类(Global.asax)中创建此类的静态实例,然后调用方法根据需要对Web请求进行排队。

在后台执行网络请求的类

public class SiteBackgroundCaller : IRegisteredObject, IDisposable
    {
        private BlockingCollection<string> requestList;

        private CancellationTokenSource queueWorkerCts;
        private Task queueWorkerThread;

        public SiteBackgroundCaller()
        {
            // Register an instance of this class with the hosting environment, so we can terminate the task gracefully.
            HostingEnvironment.RegisterObject(this);

            requestList = new BlockingCollection<string>();
            queueWorkerCts = new CancellationTokenSource();

            queueWorkerThread = new Task(queueWorkerMethod, TaskCreationOptions.LongRunning);
            queueWorkerThread.Start();
        }

        public void QueueBackgroundRequest(string uri)
        {
            requestList.Add(uri);
        }

        private void queueWorkerMethod()
        {
            while (!queueWorkerCts.IsCancellationRequested)
            {
                try
                {
                    // This line will block until there is something in the collection
                    string uri = requestList.Take(queueWorkerCts.Token);

                    if (queueWorkerCts.IsCancellationRequested)
                        return;

                    // Make the request
                    HttpWebRequest r = (HttpWebRequest)HttpWebRequest.Create(uri);
                    HttpWebResponse response = (HttpWebResponse)r.GetResponse();
                }
                catch (OperationCanceledException)
                {
                    // This may throw if the cancellation token is Cancelled.
                }
                catch (WebException)
                {
                    // Something wrong with the web request (eg timeout)
                }
            }
        }

        // Implement IRegisteredObject
        public void Stop(bool immediate)
        {
            queueWorkerCts.Cancel();
            queueWorkerThread.Wait();
        }

        // Implement IDisposable
        public void Dispose()
        {
            HostingEnvironment.UnregisterObject(this);
        }
    }

HttpApplication中的类实例(在Global.asax中)

public class Global : System.Web.HttpApplication
{
    public static SiteBackgroundCaller BackgroundCaller { get; private set; }

    protected void Application_Start(object sender, EventArgs e)
    {
        BackgroundCaller = new SiteBackgroundCaller();
    }
}

从网页排队网页请求

public partial class MyPage: System.Web.UI.Page
{
    protected override void OnLoad(EventArgs e)
    {
        Global.BackgroundCaller.QueueBackgroundRequest("http://www.example.com/service.aspx");
    }
}

答案 1 :(得分:0)

您可以创建HttpWebRequest而不读取响应:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("service.aspx");
using (var response = request.GetResponse())
{
   // typically here you would call GetResponseStream and read the content
}

您也可以使用异步变体:

using (var response = await request.GetResponseAsync())
{
}