AsyncCompletedEventArgs.UserState Property

[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]

Gets the unique identifier for the asynchronous task.

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

Syntax

Public ReadOnly Property UserState As Object
public Object UserState { get; }

Property Value

Type: System..::.Object
An object reference that uniquely identifies the asynchronous task; otherwise, nullNothingnullptra null reference (Nothing in Visual Basic) if no value has been set.

Remarks

If a class supports multiple asynchronous methods, or multiple invocations of a single method, you can determine which task raised the MethodNameCompleted event by checking the value of the UserState property. Your code will have to track these tokens, known as task IDs, as their corresponding asynchronous tasks start and complete.

The value of this property is set during the original call to the asynchronous method that started the task.

Examples

The following code example demonstrates how to use UserState to track the lifetime of asynchronous operations. The local variable used to store the values tracked by UserState is named taskID in this example. 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

Windows Phone OS

Supported in: 8.1, 8.0, 7.1, 7.0

Platforms

Windows Phone

See Also

Reference

AsyncCompletedEventArgs Class

System.ComponentModel Namespace

System.ComponentModel..::.AsyncCompletedEventHandler

System.ComponentModel..::.AsyncOperationManager

System.ComponentModel..::.AsyncOperation

Other Resources

Implementing the Event-based Asynchronous Pattern