c# - 带有更新面板的异步任务?

标签 c# asp.net asynchronous postback

哟,我已经创建了一个 WebProject 来测试是否可以创建一个 asyncTask 来更新 Progressbar:

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() 不起作用,因为它说:

You can only call the Update-methoe bevor rendering

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

编辑:

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

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

我想通过我的按钮调用它:

<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");
        }
    })
};

但是没用...

最佳答案

在另一个线程上同步读取文件不会提高您的网络应用程序的性能,检查 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 变量中,例如 session ["actualfileline"] = actualfileline。您将从您的辅助 XHR 请求访问 Session["actualfileline"]

关于c# - 带有更新面板的异步任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21461010/

相关文章:

c# - 让相机在人像模式下正常工作

c# - 如何清除服务总线主题订阅的消息

c# - 如何发送缓存控制 : no-cache in HTTP Response header?

asp.net - 链接页面的弹出缩略图

javascript - Promises 相对于 CPS 和 Continuation Functor/Monad 有哪些优势?

java - 如何使用异步套接字?

javascript - 为什么在 while 循环内等待 setInterval Promise 会导致调用量堆积?

c# - 在 asp.net c# 中更改 GridView 的选定行的颜色

c# - 如何使用 C# 查找 MS Access 数据库中不同记录的计数?

c# - 将标签的 BackColor 绑定(bind)为数据库中的十六进制颜色值