Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can void async method be used in ASP.NET user control?

I have successfully used async void method on ASP.NET Web Forms pages. However, when I tried to use the same method in a web user control, and then put this web user control to a page with async="true" setting, I keep getting this error:

An asynchronous operation cannot be started at this time. Asynchronous operations may only be started within an asynchronous handler or module or during certain events in the Page lifecycle. If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async="true" %>.

So the question is, can void async method be used in web user control and embedded in an async enabled web form page?

like image 773
jack4it Avatar asked Mar 03 '13 09:03

jack4it


People also ask

Can we use async with void?

You use the void return type in asynchronous event handlers, which require a void return type. For methods other than event handlers that don't return a value, you should return a Task instead, because an async method that returns void can't be awaited.

Can a controller method be async?

The AsyncController class enables you to write asynchronous action methods. You can use asynchronous action methods for long-running, non-CPU bound requests.

What happens when you call async method without await C#?

The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.

Is async property allowed in C#?

There is no technical reason that async properties are not allowed in C#. It was a purposeful design decision, because "asynchronous properties" is an oxymoron. Properties should return current values; they should not be kicking off background operations.


1 Answers

You can have a control call async methods if it's on a page. See the example below:

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>

The codebehind of Page.aspx is empty

Control.ascx

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

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

Control Codebehind

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.";
    }
}
like image 74
Andrew Walters Avatar answered Oct 08 '22 12:10

Andrew Walters