AsyncOperation.UserSuppliedState Property

Gets an object that is used to uniquely identify an asynchronous operation.

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

Syntax

'Declaration
Public ReadOnly Property UserSuppliedState As Object
public Object UserSuppliedState { get; }

Property Value

Type: System.Object
The state object passed to the asynchronous method invocation.

Remarks

If your class supports multiple asynchronous methods or multiple invocations of a single asynchronous method, clients will need a way to determine which asynchronous task is raising events. Your MethodNameAsync method should take a parameter of type Object that will act as a task ID. You will use this task ID when you call the AsyncOperationManager.CreateOperation method and this will associate the client's task ID with a particular invocation of your asynchronous operation. This task ID is made available to your implementation through the UserSuppliedState property.

Caution noteCaution:

Client code must provide a unique value for the UserSuppliedState property. Non-unique task IDs may cause your implementation to report progress and other events incorrectly. Your code should check for a non-unique task ID and raise an ArgumentException if one is detected.

Examples

The following code example demonstrates how to use UserSuppliedState 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; }
    //   }

}
' 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
// 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;
}
    ' Flag an operation for cancellation by removing it 
    ' from the taskID Dictionary.. 
    Public Sub CancelGetPersonsAsync(ByVal taskId As Object)
        SyncLock Me
            taskIDs.Remove(taskId)
        End SyncLock
    End Sub

    ' Check if the asynchronous operation has been canceled. 
    Public Function GetPersonsCheckForCancellation(ByVal taskId As Object) As Boolean
        SyncLock Me
            ' If the taskID is not in the taskID Dictionary, 
            ' the process has been canceled. 
            Return Not taskIDs.ContainsKey(taskId)
        End SyncLock
    End Function
End Class
// Flag an operation for cancellation by removing it
// from the taskID Dictionary..
public void CancelGetPersonsAsync(object taskId)
{
    lock (this)
    {
        taskIDs.Remove(taskId);
    }
}

// Check if the asynchronous operation has been canceled.
public bool GetPersonsCheckForCancellation(object taskId)
{
    lock (this)
    {
        // If the taskID is not in the taskID Dictionary,
        // the process has been canceled.
        return !taskIDs.ContainsKey(taskId);
    }
}

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.