Partager via


AsyncOperation Class

Microsoft Silverlight will reach end of support after October 2021. Learn more.

Tracks the lifetime of an asynchronous operation.

Inheritance Hierarchy

System.Object
  System.ComponentModel.AsyncOperation

Namespace:  System.ComponentModel
Assembly:  System (in System.dll)

Syntax

'Declaration
Public NotInheritable Class AsyncOperation
public sealed class AsyncOperation

The AsyncOperation type exposes the following members.

Properties

  Name Description
Public propertySupported by Silverlight for Windows PhoneSupported by Xbox 360 SynchronizationContext Gets the SynchronizationContext object that was passed to the constructor when the object was created by AsyncOperationManager.
Public propertySupported by Silverlight for Windows PhoneSupported by Xbox 360 UserSuppliedState Gets an object that is used to uniquely identify an asynchronous operation.

Top

Methods

  Name Description
Public methodSupported by Silverlight for Windows PhoneSupported by Xbox 360 Equals(Object) Determines whether the specified Object is equal to the current Object. (Inherited from Object.)
Protected methodSupported by Silverlight for Windows PhoneSupported by Xbox 360 Finalize Allows an object to try to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)
Public methodSupported by Silverlight for Windows PhoneSupported by Xbox 360 GetHashCode Serves as a hash function for a particular type. (Inherited from Object.)
Public methodSupported by Silverlight for Windows PhoneSupported by Xbox 360 GetType Gets the Type of the current instance. (Inherited from Object.)
Protected methodSupported by Silverlight for Windows PhoneSupported by Xbox 360 MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)
Public methodSupported by Silverlight for Windows PhoneSupported by Xbox 360 OperationCompleted Ends the lifetime of an asynchronous operation.
Public methodSupported by Silverlight for Windows PhoneSupported by Xbox 360 Post Invokes a delegate on the thread or context appropriate for the application model.
Public methodSupported by Silverlight for Windows PhoneSupported by Xbox 360 PostOperationCompleted Ends the lifetime of an asynchronous operation.
Public methodSupported by Silverlight for Windows PhoneSupported by Xbox 360 ToString Returns a string that represents the current object. (Inherited from Object.)

Top

Remarks

When you implement a class according to the Event-based Asynchronous Pattern Overview topic in the .NET Framework documentation, you may want to track the lifetime of each asynchronous operation invoked on an instance of your class. The AsyncOperation class provides ways to track and report the progress of an asynchronous task.

The following list identifies ways to use an AsyncOperation object:

  • To report progress and interim results to the client, call Post from your asynchronous worker code.

  • To indicate that an asynchronous task has completed, or to cancel a pending asynchronous task, call PostOperationCompleted.

Your class should get an AsyncOperation object for each asynchronous task by calling AsyncOperationManager.CreateOperation when each task starts. To enable the client to distinguish separate asynchronous tasks, AsyncOperationManager.CreateOperation takes a parameter for a unique client-provided token, which becomes the UserSuppliedState property. It can then be used by client code to identify the particular asynchronous task that is raising progress or completion events.

NoteNote:

The BackgroundWorker class provides a simpler programming model for handling asynchronous behavior. Implementing the event-based asynchronous pattern by using AsyncOperation is more complex, but also more flexible, and is necessary if you must be able to communicate between the parent class and the worker class by using custom events. By using BackgroundWorker, you are limited to its ProgressChanged and RunWorkerCompleted events. Depending on the scenario, the AsyncOperation pattern may have less overhead than using BackgroundWorker because it is delegate-based and not event-based.

Notes to Inheritors

Implementers must make sure that the PostOperationCompleted and Post invocations are asynchronous, so that class library providers do not need to concern themselves with potential stack overflows if they assume asynchronous behavior in a particular application model that happens to be synchronous.

For more information about how to implement asynchronous classes, see Implementing the Event-based Asynchronous Pattern in the .NET Framework documentation.

Examples

The following code example demonstrates how to use an AsyncOperation object to track the lifetime of asynchronous operations. This code example is part of a larger example provided for the System.ComponentModel.AsyncOperationManager class.

    ' Start GetPersons as an asynchronous process. 
    Public Sub GetPersonsAsync(ByVal itemsCount As Integer, _
                               ByVal name As String, _
                               ByVal taskId As Object)

        Dim asyncOp As AsyncOperation

        ' First make sure this is not an attempt to start the 
        ' same thread twice. Multiple threads will access the 
        ' taskID Dictionary, so it must be locked to serialize 
        ' access. 
        SyncLock Me
            If taskIDs.ContainsKey(taskId) Then
                Throw New ArgumentException _
                    ("Task ID already exists", "taskID")
            End If

            ' Create a new AsyncOperation object 
            ' and put it in the taskID Dictionary. 
            asyncOp = AsyncOperationManager.CreateOperation(taskId)
            taskIDs(taskId) = asyncOp
        End SyncLock

        ' Start the asynchronous process. 
        Dim myThread As New Thread(AddressOf StartThread)
        myThread.Start(New ThreadStartParms With _
             {.ItemsCount = itemsCount, .Name = name, .AsyncOp = asyncOp})

    End Sub

    Private Sub StartThread(ByVal parms As ThreadStartParms)
        GetPersons(parms.ItemsCount, parms.Name, parms.AsyncOp)
    End Sub

// Start GetPersons as an asynchronous process.
public void GetPersonsAsync
    (int itemsCount, string name, object taskId)
{
    AsyncOperation asyncOp;

    // First make sure this is not an attempt to start the 
    // same thread twice.  Multiple threads will access the
    // taskID Dictionary, so it must be locked to serialize
    // access.
    lock (this)
    {
        if (taskIDs.ContainsKey(taskId))
        {
            throw new ArgumentException
                ("Task ID already exists", "taskID");
        }

        // Create a new AsyncOperation object
        // and put it in the taskID Dictionary.
        asyncOp =
            AsyncOperationManager.CreateOperation(taskId);
        taskIDs[taskId] = asyncOp;
    }

    // Start the asynchronous process.
    // The following line is the least amount of code to do 
    // this.  It uses a lambda expression.  Following it is 
    // commented code showing an alternative method.

    new Thread(() =>
        { GetPersons(itemsCount, name, asyncOp); }).Start();

    // The alternative is to include two lines here and
    // define separately the method that they reference and
    // a class you can use to pass parameters to Thread.Start:

    //   Thread myThread = 
    //       new Thread(new ThreadStart(StartThread));
    //   myThread.Start(new ThreadStartParms 
    //       {.ItemsCount=itemsCount, 
    //        .Name=name, 
    //        .AsyncOp=asyncOp });

    //   void StartThread()
    //   {
    //      GetPersons(itemsCount, name, asyncOp);
    //   }

    //   public class ThreadStartParms)
    //   {
    //       public int ItemsCount { get; set; }
    //       public string Name { get; set; }
    //       public AsyncOp AsyncOperation { get; set; }
    //   }

}
' The worker process for data retrieval. Simulates a 
' time-consuming operation by using Thread.Sleep. 
Public Sub GetPersons(ByVal itemsCount As Integer, _
                      ByVal Name As String, _
                      ByVal asyncOperation As AsyncOperation)

    Dim canceled As Boolean = False
    Dim exception As Exception = Nothing

    Dim personList As New List(Of Person)()

    Dim i As Integer = 1
    While i <= itemsCount OrElse itemsCount = 0
        Dim currentName As String = Name + CStr(i)
        personList.Add(New Person() With { _
                .Name = currentName, _
                .Age = i, _
                .Birthday = DateTime.Today.AddYears(-i), _
                .Available = (i Mod 2 = 0) _
            })

        ' Delay 1 second for each person. 
        Thread.Sleep(1000)

        ' Report progress by using AsyncOperation to raise 
        ' the ProgressChanged event. Pass in itemsCount of 
        ' zero to see effect of catching an exception. 
        Dim percentComplete As Integer
        Try
            percentComplete = Convert.ToInt32(i * 100 / itemsCount)
        Catch ex As Exception
            exception = ex
            Exit While
        End Try

        Dim progressChangedEventArgs As _
            New GetPersonsProgressChangedEventArgs _
                (currentName, _
                 percentComplete, _
                 asyncOperation.UserSuppliedState)

        asyncOperation.Post _
            (AsyncOpProgressReportHandler, progressChangedEventArgs)

        If GetPersonsCheckForCancellation _
            (asyncOperation.UserSuppliedState) Then
            canceled = True
            Exit While
        End If

        i += 1
    End While

    ' Report completion by raising the Completed event. 
    Dim completedEventArgs As _
        New GetPersonsCompletedEventArgs _
            (personList, _
             exception, _
             canceled, _
             asyncOperation.UserSuppliedState)

    asyncOperation.PostOperationCompleted _
        (AsyncOpCompletedHandler, completedEventArgs)
End Sub
// The worker process for data retrieval.  Simulates a 
// time-consuming operation by using Thread.Sleep.
public void GetPersons
    (int itemsCount, string Name, AsyncOperation asyncOperation)
{
    bool canceled = false;
    Exception exception = null;

    List<Person> personList = new List<Person>();

    for (int i = 1; i <= itemsCount || itemsCount == 0; i++)
    {
        string currentName = Name + i;
        personList.Add(new Person()
        {
            Name = currentName,
            Age = i,
            Birthday = DateTime.Today.AddYears(-i),
            Available = (i % 2 == 0)
        });
        // Delay 1 second for each person.
        Thread.Sleep(1000);

        // Report progress by using AsyncOperation to raise
        // the ProgressChanged event.
        int percentComplete = 0;
        try
        {
            percentComplete =
                Convert.ToInt32(i * 100 / itemsCount);
        }
        catch (Exception ex)
        {
            exception = ex;
            break;
        }

        GetPersonsProgressChangedEventArgs progressChangedEventArgs =
            new GetPersonsProgressChangedEventArgs(
                currentName,
                percentComplete,
                asyncOperation.UserSuppliedState);
        asyncOperation.Post(AsyncOpProgressReportHandler,
                            progressChangedEventArgs);

        if (GetPersonsCheckForCancellation
            (asyncOperation.UserSuppliedState))
        {
            canceled = true;
            break;
        }
    }

    // Report completion by raising the Completed event.
    GetPersonsCompletedEventArgs completedEventArgs =
        new GetPersonsCompletedEventArgs(
            personList,
            exception,
            canceled,
            asyncOperation.UserSuppliedState);

    asyncOperation.PostOperationCompleted
        (AsyncOpCompletedHandler, completedEventArgs);
}

Version Information

Silverlight

Supported in: 5, 4, 3

Silverlight for Windows Phone

Supported in: Windows Phone OS 7.1, Windows Phone OS 7.0

XNA Framework

Supported in: Xbox 360, Windows Phone OS 7.0

Platforms

For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.

Thread Safety

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

See Also

Reference