【问题标题】:AsyncTask with a Updatepanel?带有更新面板的 AsyncTask?
【发布时间】:2014-02-23 00:32:39
【问题描述】:

哟,我创建了一个 WebProject 来测试是否可以创建一个 asyncTask 来更新进度条:

public partial class AsyncTest : System.Web.UI.Page
{
    private String _taskprogress;
    private AsyncTaskDelegate _dlgt;
    protected delegate void AsyncTaskDelegate();

    protected void Page_Load(object sender, EventArgs e)
    {
    }

    public String GetAsyncTaskProgress()
    {
        return _taskprogress;
    }

    public IAsyncResult OnBegin(object sender, EventArgs e,
       AsyncCallback cb, object extraData)
    {
        _taskprogress = "AsyncTask started at: " + DateTime.Now + ". ";

        _dlgt = new AsyncTaskDelegate(ReadFile);
        IAsyncResult result = _dlgt.BeginInvoke(cb, extraData);

        return result;
    }

    public void ReadFile()
    {
        try
        {
            string Filename = @"D:\Material.txt";
            int filelength = TotalLines(Filename); //just reads the lines of the file

            ProgressBar1.Maximum = filelength;

            using (StreamReader reader = new StreamReader(Filename))
            {
                string line;
                int actualfileline = 1;
                while ((line = reader.ReadLine()) != null)
                {
                    string test = line;
                    ProgressBar1.Value = actualfileline;
                    actualfileline++;
                    //UpdatePanel1.Update(); <- Doesnt work
                    System.Threading.Thread.Sleep(5);
                }
            }
        }
        catch (Exception ex)
        {
            string exm = ex.Message.ToString();
        }
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        OnBegin(this, null, null, null);

    }
}

Aaa 和我的 aspx 代码:(我当然也有一个脚本管理器)

<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:Button runat="server" ID="btnDoTask" Text="Do Task" OnClick="Button1_Click" />
        <br />
        <br />
        <eo:ProgressBar ID="ProgressBar1" runat="server" Width="250px" 
            BackgroundImage="00060301" BackgroundImageLeft="00060302" 
            BackgroundImageRight="00060303" ControlSkinID="None" IndicatorImage="00060304">
        </eo:ProgressBar
    </ContentTemplate>
</asp:UpdatePanel>

调用 Updatepanel1.Update() 不起作用,因为它说:

只能调用Update-methhoe进行渲染

那么我还能如何更新它呢? 我希望用户在进度条上看到进度——因为我想实现更大的文件读取代码。 我对异步编程真的很陌生,所以我不确定是否有你需要的一切:/

编辑:

好的,现在我在我的页面中创建了一个 Web 服务:

[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod]
public string GetProcess()
{
    if (actualfileline != null)
    {
        return actualfileline.ToString();
    }
    else
    {
        return "0";
    }
}

我想通过我的 Button 来称呼它:

<asp:Button runat="server" ID="btnDoTask" Text="Do Task" OnClick="Button1_Click" OnClientClick="StartJavaScriptProgress()" />

javascript部分:

function StartJavaScriptProgress()
{
    var elm = document.getElementById("LabelProgress");
    elm.innerText = "Currently Working ...";
    setTimeout(WebService(), 1000);
};

function WebService() {
    $.ajax(
    {
        type: "POST",
        url: "AsyncTest.aspx/GetProcess",
        data: "{}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            alert("Worked");
            var elm = document.getElementById("ProgressBar1");
            elm.value = response.d; 
        },
        error: function (jqXHR, textStatus, errorThrown) {

            alert("Error starting process");
        }
    })
};

但它不起作用......

【问题讨论】:

    标签: c# asp.net asynchronous postback


    【解决方案1】:

    在另一个线程上同步读取文件不会提高您的网络应用程序的性能,请查看this 了解更多详细信息。相反,您应该使用像 ReadLineAsync 这样的自然异步 API,并使用 RegisterAsyncTask 启用 HTTP 请求的异步完成,如下所示:

    // Make sure to enable asynchronous request processing:
    // <%@ Page Async="true" ... %>
    
    public partial class AsyncTest : System.Web.UI.Page
    {
        private String _taskprogress;
    
        protected void Page_Load(object sender, EventArgs e)
        {
        }
    
        protected void Button1_Click(object sender, EventArgs e)
        {
            RegisterAsyncTask(new PageAsyncTask(ReadFileAsync));
        }
    
        public async Task ReadFileAsync()
        {
            try
            {
                string Filename = @"D:\Material.txt";
                int filelength = TotalLines(Filename); //just reads the lines of the file
    
                ProgressBar1.Maximum = filelength;
    
                using (StreamReader reader = new StreamReader(Filename))
                {
                    string line;
                    int actualfileline = 1;
                    while ((line = await reader.ReadLineAsync()) != null)
                    {
                        string test = line;
                        ProgressBar1.Value = actualfileline;
                        actualfileline++;
                        //UpdatePanel1.Update(); <- Doesnt work
                        System.Threading.Thread.Sleep(5);
                    }
                }
            }
            catch (Exception ex)
            {
                string exm = ex.Message.ToString();
            }
        }
    }
    

    请注意,这仍然不会更新客户端页面中的进度 UI。这样做是使 当前 HTTP 请求以异步方式完成 服务器端。浏览器仍将等待它。这提高了您的 Web 应用程序的可伸缩性,但客户端的网页只有在 ReadFileAsync 完全完成后才会呈现。

    如果您想在客户端提供进度更新,您应该使用 AJAX 并通过 XHR 请求或在隐藏框架内启动上述冗长的过程。然后,您将能够使用辅助 XHR 请求跟踪其进度并更新 UI。在ReadFileAsync 中,您需要将进度信息保存在会话变量中,例如Session["actualfileline"] = actualfileline。您将从辅助 XHR 请求中访问 Session["actualfileline"]

    【讨论】:

    • 谢谢!我需要找到另一种方式,然后我想......只要我找到了我需要的东西,我会发布它并接受你的回答:) 抱歉回复晚了。
    • @DatRid,没问题。您可能想检查一下:Long Running Background Tasks in Asp.Net MVC3.
    猜你喜欢
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    • 2011-11-16
    • 1970-01-01
    • 1970-01-01
    • 2015-07-16
    相关资源
    最近更新 更多