AsyncOperationManager Class
Microsoft Silverlight will reach end of support after October 2021. Learn more.
Provides concurrency management for classes that support asynchronous method calls. This class cannot be inherited.
Inheritance Hierarchy
System.Object
System.ComponentModel.AsyncOperationManager
Namespace: System.ComponentModel
Assembly: System (in System.dll)
Syntax
'Declaration
Public NotInheritable Class AsyncOperationManager
public static class AsyncOperationManager
The AsyncOperationManager type exposes the following members.
Properties
Name | Description | |
---|---|---|
SynchronizationContext | Gets or sets the SynchronizationContext for the asynchronous operation. |
Top
Methods
Name | Description | |
---|---|---|
CreateOperation | Returns an AsyncOperation for tracking the duration of a particular asynchronous operation. |
Top
Remarks
If your class must provide asynchronous behavior according to the Event-based Asynchronous Pattern Overview topic in the .NET Framework documentation, your scenario may also have concurrency management requirements. Among these is the requirement to make sure that event handlers are called on a thread or context that is appropriate for the application model (for example, Windows Forms applications, ASP.NET applications, console applications, Silverlight-based applications, and so on). The AsyncOperationManager provides a convenient way to create a class that runs correctly under all application models supported by the .NET Framework.
The AsyncOperationManager class has one method, CreateOperation, which returns an System.ComponentModel.AsyncOperation object that can be used to track the duration of a particular asynchronous task. The System.ComponentModel.AsyncOperation for a task can be used to alert clients when a task completes. It can also be used to post progress updates and incremental results without terminating the operation.
For more information about how to implement asynchronous classes, see Implementing the Event-based Asynchronous Pattern in the .NET Framework documentation.
Note: |
---|
The BackgroundWorker class provides a simpler programming model for handling asynchronous behavior. Implementing the event-based asynchronous pattern by using AsyncOperationManager 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 AsyncOperationManager pattern may have less overhead than using BackgroundWorker because it is delegate-based and not event-based. |
Examples
The following code example demonstrates how to use the AsyncOperationManager class to create a class that supports asynchronous operations for any application model. It simulates a long-running data-gathering operation by using Thread.Sleep statements. Progress reports, incremental results, cancellation, and completion notifications are handled by the AsyncOperation class, which makes sure that the client's event handlers are called on the correct thread or context. Asynchronous processing is started when the Load button is clicked. When the operation is complete, the data is shown in a DataGrid control. After it starts, the operation's progress is shown in a box below the buttons, the Load button is disabled, and the Cancel button is enabled.
The MainPage class represents the user interface and performs the following functions:
Calls the ReturnRows method of the PersonDataSource class asynchronously.
Disables the Load button and enables the Cancel button when the process starts.
Updates the progress reporting text boxes during the load process.
Provides a status message when the operation ends.
The Person class shows the format of the data that is returned by the PersonDataSource class and displayed by the DataGrid. The PersonDataSource class supports asynchronous processing for the simulated long-running data-gathering operation.
<!-- NOTE:
By convention, the sdk prefix indicates a URI-based XAML namespace declaration
for Silverlight SDK client libraries. This namespace declaration is valid for
Silverlight 4 only. In Silverlight 3, you must use individual XAML namespace
declarations for each CLR assembly and namespace combination outside the scope
of the default Silverlight XAML namespace. For more information, see the help
topic "Prefixes and Mappings for Silverlight Libraries".
-->
<UserControl x:Class="AsyncOperationManagerExample.MainPage"
xmlns:sdk="https://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="500">
<StackPanel x:Name="LayoutRoot" Background="White">
<sdk:DataGrid x:Name="dg"
AutoGenerateColumns="False"
IsReadOnly="False"
Height="250">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="Name"
Binding="{Binding Name}" />
<sdk:DataGridTextColumn Header="Age"
Binding="{Binding Age}" />
<sdk:DataGridTextColumn Header="Birth Date"
Binding="{Binding Birthday}" />
<sdk:DataGridTextColumn Header="Available"
Binding="{Binding Available}" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<StackPanel Orientation="Horizontal">
<Button x:Name="loadButton" Content="Load" Width="190"
Margin="5" Click="loadButton_Click"/>
<Button x:Name="cancelButton" Content="Cancel" Width="190"
Margin="5" Click="cancelButton_Click" IsEnabled="False"/>
</StackPanel>
<Border BorderBrush="Black"
BorderThickness="1" Padding="2" Margin="5">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Width="150" TextAlignment="Right"
Text="Percent Complete: "/>
<TextBlock x:Name="percentCompleteTextBlock"
FontWeight="Bold"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Width="150" TextAlignment="Right"
Text="Latest Name: " />
<TextBlock x:Name="latestNameTextBlock"
FontWeight="Bold"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Width="150" TextAlignment="Right"
Text="Status: " />
<TextBlock x:Name="statusMessageBlock"
FontWeight="Bold"/>
</StackPanel>
</StackPanel>
</Border>
</StackPanel>
</UserControl>
Partial Public Class MainPage
Inherits UserControl
Private WithEvents pds As New PersonDataSource()
Public Sub New()
InitializeComponent()
End Sub
Private Sub loadButton_Click _
(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Start the asynchronous operation.
' Change the "10" to "0"
' to see what happens when an error happens
' in the asynchronous process.
pds.GetPersonsAsync(10, "Smith", "1")
loadButton.IsEnabled = False
cancelButton.IsEnabled = True
statusMessageBlock.Text = "Loading"
End Sub
Private Sub cancelButton_Click _
(ByVal sender As Object, ByVal e As RoutedEventArgs)
pds.CancelGetPersonsAsync("1")
cancelButton.IsEnabled = False
End Sub
Private Sub pds_GetPersonsCompletedEvent _
(ByVal sender As Object, _
ByVal e As GetPersonsCompletedEventArgs) _
Handles pds.GetPersonsCompletedEvent
' Upon completion, set the status message based on
' whether the operation was canceled, errored, or successful.
If e.Cancelled Then
statusMessageBlock.Text = "Canceled"
ElseIf e.Error IsNot Nothing Then
statusMessageBlock.Text = "Errored"
Else
dg.ItemsSource = e.DataListValue
statusMessageBlock.Text = "Successfully completed"
End If
End Sub
Private Sub pds_GetPersonsProgressChangedEvent _
(ByVal e As GetPersonsProgressChangedEventArgs) _
Handles pds.GetPersonsProgressChangedEvent
percentCompleteTextBlock.Text = _
e.ProgressPercentage.ToString()
latestNameTextBlock.Text = e.LatestName
End Sub
End Class
using System;
using System.Windows;
using System.Windows.Controls;
namespace AsyncOperationManagerExample
{
public partial class MainPage : UserControl
{
PersonDataSource pds = new PersonDataSource();
public MainPage()
{
InitializeComponent();
}
void loadButton_Click(object sender, RoutedEventArgs e)
{
// Start the asynchronous operation and register
// event handlers for its ProgressChanged and
// Completed events. Change the "10" to "0"
// to see what happens when an error happens
// in the asynchronous process.
pds.GetPersonsAsync(10, "Smith", "1");
pds.GetPersonsProgressChangedEvent +=
new PersonDataSource.GetPersonsProgressChangedEventHandler
(pds_GetPersonsProgressChangedEvent);
pds.GetPersonsCompletedEvent +=
new PersonDataSource.GetPersonsCompletedEventHandler
(pds_GetPersonsCompletedEvent);
loadButton.IsEnabled = false;
cancelButton.IsEnabled = true;
statusMessageBlock.Text = "Loading";
}
void cancelButton_Click(object sender, RoutedEventArgs e)
{
// Call the Cancel method, passing in the ID of the
// thread to cancel.
pds.CancelGetPersonsAsync("1");
cancelButton.IsEnabled = false;
}
void pds_GetPersonsCompletedEvent
(object sender, GetPersonsCompletedEventArgs e)
{
// Upon completion, set the status message based on
// whether the operation was canceled, errored, or successful.
if (e.Cancelled)
{
statusMessageBlock.Text = "Canceled";
}
else if (e.Error != null)
{
statusMessageBlock.Text = "Errored";
}
else
{
dg.ItemsSource = e.DataListValue;
statusMessageBlock.Text = "Successfully completed";
}
}
void pds_GetPersonsProgressChangedEvent
(GetPersonsProgressChangedEventArgs e)
{
percentCompleteTextBlock.Text =
e.ProgressPercentage.ToString();
latestNameTextBlock.Text = e.LatestName;
}
}
}
' Format of data retrieved and bound to the GridView control.
Public Class Person
Private _Name As String
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
Private _Age As Integer
Public Property Age() As Integer
Get
Return _Age
End Get
Set(ByVal value As Integer)
_Age = value
End Set
End Property
Private _Birthday As DateTime
Public Property Birthday() As DateTime
Get
Return _Birthday
End Get
Set(ByVal value As DateTime)
_Birthday = value
End Set
End Property
Private _Available As Boolean
Public Property Available() As Boolean
Get
Return _Available
End Get
Set(ByVal value As Boolean)
_Available = value
End Set
End Property
End Class
using System;
namespace AsyncOperationManagerExample
{
// Format of data retrieved and bound to the GridView control.
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public DateTime Birthday { get; set; }
public bool Available { get; set; }
}
}
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Threading
Public Class PersonDataSource
' Declare a dictionary to track taskIDs. This will be used
' to ensure that attempts to start the same thread more than
' once will be caught.
Private taskIDs As New Dictionary(Of Object, Object)()
' Declare delegates and events for Completed and
' ProgressChanged methods for this class's
' GetPersonsAsync method.
Public Delegate Sub GetPersonsCompletedEventHandler _
(ByVal sender As Object, _
ByVal e As GetPersonsCompletedEventArgs)
Public Delegate Sub GetPersonsProgressChangedEventHandler _
(ByVal e As GetPersonsProgressChangedEventArgs)
Public Event GetPersonsCompletedEvent _
As GetPersonsCompletedEventHandler
Public Event GetPersonsProgressChangedEvent _
As GetPersonsProgressChangedEventHandler
' The GetPersons method will raise ProgressChanged and
' Completed events by using AsyncOperation's Post
' and PostOperationCompleted methods. Declare delegates
' for them here. Methods for use
' with these delegates will be defined below.
Private AsyncOpProgressReportHandler As SendOrPostCallback
Private AsyncOpCompletedHandler As SendOrPostCallback
' Constructor
Public Sub New()
' Attach the Completed and ProgressChanged methods that will
' be called by AsyncOperation to their delegates.
AsyncOpProgressReportHandler = New SendOrPostCallback _
(AddressOf AsyncOpGetPersonsProgressChanged)
AsyncOpCompletedHandler = New SendOrPostCallback _
(AddressOf AsyncOpGetPersonsCompleted)
End Sub
' ProgressChanged method for passing in to the
' AsyncOperation Post method.
Protected Sub AsyncOpGetPersonsProgressChanged(ByVal state As Object)
Dim progressChangedEventArgs As GetPersonsProgressChangedEventArgs _
= TryCast(state, GetPersonsProgressChangedEventArgs)
OnGetPersonsProgressChanged(progressChangedEventArgs)
End Sub
' Completed-event method for passing in to the
' AsyncOperation PostOperationCompleted method.
Protected Sub AsyncOpGetPersonsCompleted(ByVal eventArgs As Object)
Dim completedEventArgs As GetPersonsCompletedEventArgs _
= TryCast(eventArgs, GetPersonsCompletedEventArgs)
OnGetPersonsCompleted(completedEventArgs)
End Sub
' Raise the ProgressChanged event.
Protected Sub OnGetPersonsProgressChanged _
(ByVal e As GetPersonsProgressChangedEventArgs)
RaiseEvent GetPersonsProgressChangedEvent(e)
End Sub
' Raise the Completed event.
Protected Sub OnGetPersonsCompleted _
(ByVal e As GetPersonsCompletedEventArgs)
RaiseEvent GetPersonsCompletedEvent(Me, e)
End Sub
' 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
' 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
' 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
' Define a Thread.Start parameters class allowing
' parameters to be sent in to the Thread.Start method.
Public Class ThreadStartParms
Private _itemsCount As Integer
Public Property ItemsCount() As Integer
Get
Return _itemsCount
End Get
Set(ByVal value As Integer)
_itemsCount = value
End Set
End Property
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Private _asyncOp As AsyncOperation
Public Property AsyncOp() As AsyncOperation
Get
Return _asyncOp
End Get
Set(ByVal value As AsyncOperation)
_asyncOp = value
End Set
End Property
End Class
' Define a custom Completed-event arguments class allowing
' the data gathered by GetPersons to be returned.
Public Class GetPersonsCompletedEventArgs
Inherits AsyncCompletedEventArgs
Private m_dataListValue As List(Of Person)
Public Sub New _
(ByVal dataList As List(Of Person), _
ByVal exception As Exception, _
ByVal cancelled As Boolean, _
ByVal userState As Object)
MyBase.New(exception, cancelled, userState)
m_dataListValue = dataList
End Sub
Public ReadOnly Property DataListValue() As List(Of Person)
Get
Me.RaiseExceptionIfNecessary()
Return m_dataListValue
End Get
End Property
End Class
' Define a custom ProgressChanged arguments class allowing last
' name loaded as well as progress percentage to be returned.
Public Class GetPersonsProgressChangedEventArgs
Inherits ProgressChangedEventArgs
Private latestNameValue As String = String.Empty
Public Sub New _
(ByVal latestName As String, _
ByVal progressPercentage As Integer, _
ByVal userState As Object)
MyBase.New(progressPercentage, userState)
latestNameValue = latestName
End Sub
Public ReadOnly Property LatestName() As String
Get
Return latestNameValue
End Get
End Property
End Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
namespace AsyncOperationManagerExample
{
public class PersonDataSource
{
// Declare a dictionary to track taskIDs. This will be used
// to ensure that attempts to start the same thread more than
// once will be caught.
private Dictionary<object, object> taskIDs =
new Dictionary<object, object>();
// Declare delegates and events for Completed and
// ProgressChanged methods for this class's
// GetPersonsAsync method.
public delegate void GetPersonsCompletedEventHandler
(object sender, GetPersonsCompletedEventArgs e);
public delegate void GetPersonsProgressChangedEventHandler
(GetPersonsProgressChangedEventArgs e);
public event GetPersonsCompletedEventHandler
GetPersonsCompletedEvent;
public event GetPersonsProgressChangedEventHandler
GetPersonsProgressChangedEvent;
// The GetPersons method will raise ProgressChanged and
// Completed events by using AsyncOperation's Post
// and PostOperationCompleted methods. Declare delegates
// for them here. Methods for use
// with these delegates will be defined below.
private SendOrPostCallback AsyncOpProgressReportHandler;
private SendOrPostCallback AsyncOpCompletedHandler;
// Constructor
public PersonDataSource()
{
// Attach the Completed and ProgressChanged events that
// will be called by AsyncOperation to their delegates.
AsyncOpProgressReportHandler =
new SendOrPostCallback(AsyncOpGetPersonsProgressChanged);
AsyncOpCompletedHandler =
new SendOrPostCallback(AsyncOpGetPersonsCompleted);
}
// ProgressChanged method for passing in to the
// AsyncOperation Post method.
protected void AsyncOpGetPersonsProgressChanged(object state)
{
GetPersonsProgressChangedEventArgs e
= state as GetPersonsProgressChangedEventArgs;
OnGetPersonsProgressChanged(e);
}
// Completed-event method for passing in to the
// AsyncOperation PostOperationCompleted method.
protected void AsyncOpGetPersonsCompleted(object eventArgs)
{
GetPersonsCompletedEventArgs e =
eventArgs as GetPersonsCompletedEventArgs;
OnGetPersonsCompleted(e);
}
// Raise the ProgressChanged event.
protected void OnGetPersonsProgressChanged
(GetPersonsProgressChangedEventArgs e)
{
if (GetPersonsProgressChangedEvent != null)
{
GetPersonsProgressChangedEvent(e);
}
}
// Raise the Completed event.
protected void OnGetPersonsCompleted
(GetPersonsCompletedEventArgs e)
{
if (GetPersonsCompletedEvent != null)
{
GetPersonsCompletedEvent(this, e);
}
}
// 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);
}
// 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; }
// }
}
// 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);
}
}
}
// Define a custom Completed-event arguments class allowing
// the data gathered by GetPersons to be returned.
public class GetPersonsCompletedEventArgs : AsyncCompletedEventArgs
{
private List<Person> dataListValue;
public GetPersonsCompletedEventArgs(
List<Person> dataList,
Exception error,
bool cancelled,
object userState)
: base(error, cancelled, userState)
{
dataListValue = dataList;
}
public List<Person> DataListValue
{
get
{
this.RaiseExceptionIfNecessary();
return dataListValue;
}
}
}
// Define a custom ProgressChanged arguments class allowing last
// name loaded as well as progress percentage to be returned.
public class GetPersonsProgressChangedEventArgs
: ProgressChangedEventArgs
{
private string latestNameValue = string.Empty;
public GetPersonsProgressChangedEventArgs(
string latestName,
int progressPercentage,
object userState)
: base(progressPercentage, userState)
{
latestNameValue = latestName;
}
public string LatestName
{
get
{
return latestNameValue;
}
}
}
}
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