2

私は今数日検索し、見つけたすべての解決策について試しました。私はこれが私が正しくやっていないことであることを知っています、しかし、私は正しい方法が何であるかわかりません。

.Net Framework4.5で実行されているASP.NetC#Webサイトがあります。フォームにリンクボタンがあります。クリックすると、ThreadPoolを使用して長時間実行されているプロセスが起動します。デリゲートコールバックを設定していますが、プロセスがキャンセルされたとき、またはプロセスが終了したときにコードが起動します。(私はプロセスをキャンセルするためにキャンセルトークンを使用しています。重要な場合、プロセスはアクティブレポートです。)

私が言ったように、コールバックコードが起動したときにjavascriptを実行しないことを除いて、すべてがうまく機能します。(参考までに、これはjavascriptコールバックではなく、プロセスの終了時にいくつかのjavascriptコードを起動しようとしているだけです。)

これが私がレポートを開始するコードです...

文字列sThreadID=Thread.CurrentThread.ManagedThreadId.ToString(); ThreadPool.QueueUserWorkItem(new WaitCallback(StartReport)、cts.Token);

StartReportのコードは次のとおりです。

public static void StartReport(object obj) {
    try {
        OnTaskCompleteDelegate callback = new OnTaskCompleteDelegate(OnTaskComplete);
        BoyceReporting.CallReport(boyce.BoyceThreadingEnvironment.OBRO, "THREADING");
        if (boyce.BoyceThreadingEnvironment.CTS.Token.IsCancellationRequested) {
            boyce.BoyceThreadingEnvironment.SESSION.sScriptToExecute = "alert('Report Canceled By User');";
            callback("CANCELED");
        } else {
            callback("FINISHED");
        }
    } catch {
        throw;
    }
}

これがコールバックコードのコードです.....

public static void OnTaskComplete(string ReportResult) {
    try {
        sReportResult = ReportResult;
        if (ReportResult == "CANCELED") {
            //  In case we need to do additional things if the report is canceled
        }
        string sThreadID = Thread.CurrentThread.ManagedThreadId.ToString();
        boyce.BoyceThreadingEnvironment.THISPAGE.ClientScript.RegisterStartupScript(boyce.BoyceThreadingEnvironment.THISPAGE.GetType(), "FireTheScript" + DateTime.Now.ToString(), boyce.BoyceThreadingEnvironment.SESSION.sScriptToExecute, true);
        ScriptManager.RegisterStartupScript(boyce.BoyceThreadingEnvironment.THISPAGE, boyce.BoyceThreadingEnvironment.THISPAGE.GetType(), "DisplayReport" + DateTime.Now.ToString(), boyce.BoyceThreadingEnvironment.SESSION.sScriptToExecute, true);
    } catch {
        throw;
    }
}

これが私が抱えている問題です.....

スクリプトを起動するコードの最後の行を取得できないことを除いて、すべてが正常に機能します。ScriptManager.RegisterStartupScript

これが私が起こっていると思うことです.....

スレッドIDを見ると、コードが起動されない理由は、Call Backイベントで起動しようとしているScriptManagerコードが、メインスレッド以外の別のスレッドにあるためだと確信しています。

これが私の質問です。

(1)これがJavaScriptを起動しない理由は正しいですか?(2)(CallBackの内部から)このJavaScriptを起動するにはどうすればよいですか?これをメインスレッドで強制的に実行する方法はありますか?

4

2 に答える 2

1

新しいスレッドをスピンオフしているため、JSでは起動しません。その間、リクエストはクライアントに返され、接続を閉じてからかなり経ちました。スレッドが応答に何かを書き出そうとするときまでに、それはすでに終了しています。

このようにする代わりに、の内部でボタンをクリックするだけです(またはレポートを開始するものは何でも)UpdatePanel。そうすれば、新しいスレッドを起動する必要はありません。

于 2013-03-06T16:43:33.123 に答える
0
Here is the cod I used in the C# Code Behind to call the web service to start monitoring this process.
----------------------------------------------------------------------------------------------

                CurrentSession.bIsReportRunning = true;
                ScriptManager.RegisterStartupScript(this, this.GetType(), "WaitForReport" + DateTime.Now.ToString(), "jsWaitOnCallReport();", true);
                MultiThreadReport.RunTheReport(HttpContext.Current, CurrentSession, this, oBRO);

Here is the code that calls the method, using the threadpool, and the method called..
----------------------------------------------------------------------------------------------
            ThreadPool.QueueUserWorkItem(new WaitCallback(StartReport), cts.Token);

    public static void StartReport(object obj) {
        try {
            OnTaskCompleteDelegate callback = new OnTaskCompleteDelegate(OnTaskComplete);
            BoyceReporting.CallReport(boyce.BoyceThreadingEnvironment.OBRO, "THREADING");
            HttpContext.Current = boyce.BoyceThreadingEnvironment.CONTEXT;
            if (boyce.BoyceThreadingEnvironment.CTS.Token.IsCancellationRequested) {
                boyce.BoyceThreadingEnvironment.SESSION.sScriptToExecute = "alert('Report Canceled By User');";
                boyce.BoyceThreadingEnvironment.SESSION.bIsReportRunning = false;
                callback("CANCELED");
            } else {
                boyce.BoyceThreadingEnvironment.SESSION.bIsReportRunning = false;
                callback("FINISHED");
            }
        } catch {
            throw;
        }
    }

Here is the web service method I created to monitor the process, with a built in safety net
--------------------------------------------------------------------------------------------

    [WebMethod(EnableSession = true)]
    public string WaitOnReport() {
        try {
            HttpContext.Current = boyce.BoyceThreadingEnvironment.CONTEXT;
            SessionManager CurrentSession;
            CurrentSession = (SessionManager)boyce.BoyceThreadingEnvironment.SESSION;

            DateTime dtStartTime = DateTime.Now;
            DateTime dtCurrentTime = DateTime.Now;
            if (CurrentSession != null) {
                do {
                    //  Build a safety limit into this loop to avoid an infinate loope
                    //  If this runs longer than 20 minutes, then force an error due to timeout
                    //  This timeout should be lowered when they find out what the issue is with 
                    //  the "long running reports".  For now, I set it to 20 minutes but shoud be MUCH lower.
                    dtCurrentTime = DateTime.Now;
                    TimeSpan span = dtCurrentTime-dtStartTime;
                    double totalMinutes = span.TotalMinutes;
                    if (totalMinutes>=20) {
                        return "alert('Error In Creating Report (Time-Out)');";
                    }
                } while (CurrentSession.bIsReportRunning == true);
                //  If all goes well, return the script to either OPEN the report or display CANCEL message
                return CurrentSession.sScriptToExecute;
            } else {
                return "alert('Error In Creating Report (Session)');";
            }
        } catch {
            throw;
        }
    }


And here is the JavaScript code I used to initiate the Web Service Call and Also The Postback
--------------------------------------------------------------------------------------------
function jsWaitOnCallReport() {
    try {
        var oWebService = BoyceWebService.WaitOnReport(jsWaitOnCallReport_CallBack);
    } catch (e) {
        alert('Error In Calling Report Screen -- ' + e);
    }
}
function jsWaitOnCallReport_CallBack(result) {
    try {
        eval(result); 
        var myExtender = $find('ModalPopupExtenderPROGRESS');
        if (myExtender != null) {
            try {
                myExtender.hide();
            } catch (e) {
                //  Ignore Any Error That May Be Thrown Here
            }
        }
        $find('PROGRESS').hide();
    } catch (e) {
        alert('Error In Opening Report Screen -- ' + e);
    }
}

Hope this helps someone else out..  Like I said, I am not sure this is the best solution, but it works..   I would be interested in other solutions for this issue to try...  Thanks.
于 2013-03-07T01:20:42.683 に答える