AsyncOperation.UserSuppliedState Property
[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]
Gets an object that is used to uniquely identify an asynchronous operation.
Assembly: System (in System.dll)
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: |
|---|
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. |
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 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. 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 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); } }
Caution: