可以在ASP.NET用户控件中使用void异步方法吗?

时间:2013-03-03 09:08:05

标签: asp.net asynchronous user-controls void

我在ASP.NET Web窗体页面上成功使用了async void方法。但是,当我尝试在Web用户控件中使用相同的方法,然后将此Web用户控件放到设置为async="true"的页面时,我不断收到此错误:

  

此时无法启动异步操作。异步操作可能   只能在异步中启动   处理程序或模块或在页面生命周期中的某些事件期间。如果   执行页面时发生此异常,确保页面   标记为<%@ Page Async =“true”%>。

所以问题是,可以在Web用户控件中使用void async方法并将其嵌入到启用异步的Web表单页面中吗?

1 个答案:

答案 0 :(得分:7)

如果它在页面上,您可以拥有控制调用异步方法。请参阅以下示例:

<强> Page.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Page.aspx.cs" Inherits="AsyncDEmo.Page" Async="true" %>

<%@ Register Src="~/Control.ascx" TagPrefix="uc1" TagName="Control" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <uc1:Control runat="server" id="Control" />
    </form>
</body>
</html>

Page.aspx的代码隐藏是空的

<强> Control.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Control.ascx.cs" Inherits="AsyncDEmo.Control" %>

<span id="TaskMessage" runat="server">
      </span>

控制代码隐藏

protected void Page_Load(object sender, EventArgs e)
    {
        // Define the asynchronuous task.
        Samples.AspNet.CS.Controls.SlowTask slowTask1 =
          new Samples.AspNet.CS.Controls.SlowTask();
        Samples.AspNet.CS.Controls.SlowTask slowTask2 =
        new Samples.AspNet.CS.Controls.SlowTask();
        Samples.AspNet.CS.Controls.SlowTask slowTask3 =
        new Samples.AspNet.CS.Controls.SlowTask();

        PageAsyncTask asyncTask1 = new PageAsyncTask(slowTask1.OnBegin, slowTask1.OnEnd, slowTask1.OnTimeout, "Async1", true);
        PageAsyncTask asyncTask2 = new PageAsyncTask(slowTask2.OnBegin, slowTask2.OnEnd, slowTask2.OnTimeout, "Async2", true);
        PageAsyncTask asyncTask3 = new PageAsyncTask(slowTask3.OnBegin, slowTask3.OnEnd, slowTask3.OnTimeout, "Async3", true);

        // Register the asynchronous task.
        Page.RegisterAsyncTask(asyncTask1);
        Page.RegisterAsyncTask(asyncTask2);
        Page.RegisterAsyncTask(asyncTask3);

        // Execute the register asynchronous task.
        Page.ExecuteRegisteredAsyncTasks();

        TaskMessage.InnerHtml = slowTask1.GetAsyncTaskProgress() + "<br />" + slowTask2.GetAsyncTaskProgress() + "<br />" + slowTask3.GetAsyncTaskProgress();
    }

<强> SlowClass.cs

public class SlowTask
{
    private String _taskprogress;
    private AsyncTaskDelegate _dlgt;

    // Create delegate. 
    protected delegate void AsyncTaskDelegate();

    public String GetAsyncTaskProgress()
    {
        return _taskprogress;
    }
    public void ExecuteAsyncTask()
    {
        // Introduce an artificial delay to simulate a delayed  
        // asynchronous task.
        Thread.Sleep(TimeSpan.FromSeconds(5.0));
    }

    // Define the method that will get called to 
    // start the asynchronous task. 
    public IAsyncResult OnBegin(object sender, EventArgs e,
        AsyncCallback cb, object extraData)
    {
        _taskprogress = "AsyncTask started at: " + DateTime.Now + ". ";

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

        return result;
    }

    // Define the method that will get called when 
    // the asynchronous task is ended. 
    public void OnEnd(IAsyncResult ar)
    {
        _taskprogress += "AsyncTask completed at: " + DateTime.Now;
        _dlgt.EndInvoke(ar);
    }

    // Define the method that will get called if the task 
    // is not completed within the asynchronous timeout interval. 
    public void OnTimeout(IAsyncResult ar)
    {
        _taskprogress += "AsyncTask failed to complete " +
            "because it exceeded the AsyncTimeout parameter.";
    }
}