【问题标题】:How to send multiple acknowledgement to client using IHttpAsyncHandler in asp.net如何在 asp.net 中使用 IHttpAsyncHandler 向客户端发送多个确认
【发布时间】:2014-04-18 13:01:38
【问题描述】:

我已经在我的班级中实现了 IHttpAsyncHandler 以在后台执行 5-6 个长时间运行的进程,并在每个任务开始时向客户端确认。

之前我使用一个会话变量并使用当前任务状态更新它,并以 5 秒的间隔从 jquery 向服务器发出异步调用请求以获取当前状态,但这种实现并不好,因为它不断地击中请求服务器的状态。

然后我在我的应用程序中实现了 IHttpAsyncHandler,现在服务器本身向客户端发送确认,但根据我的实现,我只能发送一个确认!如果我尝试发送多个,则其给出错误为“对象引用未设置为对象的实例”

请检查我的示例代码。

在我的代码中 ExecuteFirst() 方法可以很好地向客户端发送确认,但 ExecuteSecond() 不会发送确认它的错误。

我看了很多,但没有找到正确的方式向客户发送多个确认。

这是我的示例代码,如果有人有任何想法,请帮助我。

Javascript

function postRequest(url) {

        var url = 'StartLongRunningProcess.ashx?JOBCODE=18'

        var xmlhttp = getRequestObject();

        xmlhttp.open("POST", url, true);


        xmlhttp.onreadystatechange =
                    function () {

                        if (xmlhttp.readyState == 4) {
                            var response = xmlhttp.responseText;
                            divResponse.innerHTML += "<p>" + response + "</p>";                             
                        }
                    }


        xmlhttp.send();

    }



 function getRequestObject() {
        var req;

        if (window.XMLHttpRequest && !(window.ActiveXObject)) {
            try {
                req = new XMLHttpRequest();
            }
            catch (e) {
                req = false;
            }
        }
        else if (window.ActiveXObject) {
            try {
                req = new ActiveXObject('Msxml2.XMLHTTP');
            }
            catch (e) {
                try {
                    req = new ActiveXObject('Microsoft.XMLHTTP');
                }
                catch (e) {
                    req = false;
                }
            }
        }

        return req;
    }

StartLongRunningProcess.ashx.cs

public class StartLongRunningProcess: IHttpAsyncHandler, IRequiresSessionState
{

            private AsyncRequestResult _asyncResult;
    public void ProcessRequest(HttpContext context) {}

    public bool IsReusable
    {
        get { return true;}
    }


    public IAsyncResult BeginProcessRequest(HttpContext context, System.AsyncCallback cb, object extraData)
    {

        int32 jobCode= convert.ToInt32(context.Request["JOBCODE"]);
        _asyncResult = new AsyncRequestResult(context, cb, jobCode);

                  if(jobCode==18)
                  {

                   StartProcess18()

                  }
                  else
                  {

                   //StartProcessOther()

                  }
}



            private StartProcess18()
            {

                var task1= new Task(() =>
                {
                     ExecuteFirst();                           
                });


                var task2 = task1.ContinueWith((t1) =>
                {
                    ExecuteSecond();
                }, TaskContinuationOptions.OnlyOnRanToCompletion);

                task1.Start();
            }



    private ExecuteFirst()
    {

          //notify to client that this job has been started
         _asyncResult.CurrentContext.Response.Write("First task has been started"); 
         _asyncResult.Notify();

         // Above line of code successfully send a acknowledgement to client 

         //Doing some long running process
    }


    private ExecuteSecond()
    {

          //notify to client that this job has been started
         _asyncResult.CurrentContext.Response.Write("Second task has been started"); 

          // Above line of code giving error and if I skip it and call Notify() this also does not work.

         _asyncResult.Notify();


         //Doing some long running process
    }

    public void EndProcessRequest(IAsyncResult result)
{

}


 }

AsyncRequestResult.cs

public class AsyncRequestResult : IAsyncResult 
{
    private HttpContext context;
    private AsyncCallback callback;     

    private ManualResetEvent completeEvent = null;
    private object data;
    private object objLock = new object();
    private bool isComplete = false;        

    public AsyncRequestResult(HttpContext ctx, AsyncCallback cb, object d)
    {
        this.context = ctx;
        this.callback = cb;
        this.data = d;
    }

    public HttpContext Context
    {
        get { return this.context; }
    }

    public void Notify()
    {
        //isComplete = true;


        lock(objLock)
        {
            if(completeEvent != null)
            {
                completeEvent.Set();
            }
        }


        if (callback != null)
        {
            callback(this);
        }
    }


    public object AsyncState
    {
        get { return this.data; }
    }


    public bool CompletedSynchronously
    {
        get { return false; }
    }


    public WaitHandle AsyncWaitHandle
    {
        get
        {
            lock(objLock)
            {
                if (completeEvent == null)
                    completeEvent = new ManualResetEvent(false);

                return completeEvent;
            }
        }
    }


    public bool IsCompleted
    {
        get { return this.isComplete; }
    }

}

【问题讨论】:

    标签: c# asp.net-4.0 activexobject iasyncresult ihttpasynchandler


    【解决方案1】:

    HttpContext.Current 只有在处理传入请求的线程中访问它时才为空。

    您正在运行的延续任务很可能在ThreadPool 线程上运行,而HttpContext.Current 没有流向延续,因此它为空。

    尝试将您的 TaskScheduler 设置为 TaskScheduler.FromCurrentSynchronizationContext() 以便在相同的上下文中执行它。

            private StartProcess18()
            {
    
                var task1= new Task(() =>
                {
                     ExecuteFirst();                           
                });
    
    
                var task2 = task1.ContinueWith((t1) =>
                {
                    ExecuteSecond();
                }, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.FromCurrentSynchronizationContext());
    
                task1.Start();
            }
    

    【讨论】:

    • 这不起作用,当我在我的代码中添加“TaskScheduler.FromCurrentSynchronizationContext()”时它给出了错误。
    • 是的,我明天一到办公室就送你
    • 这是我收到的错误“当前 SynchronizationContext 可能无法用作 TaskScheduler”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 2013-10-18
    • 2017-09-11
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    • 2017-09-22
    相关资源
    最近更新 更多