Working with Asynchronous Methods in XNA Game Studio
This topic decribes how you can work with asynchronous methods in XNA Game Studio.
Complete Sample
The code in this tutorial illustrates the technique described in the text. A complete code sample for this tutorial is available for you to download, including full source code and any additional supporting files required by the sample.
Download StorageDemo_AsyncDevice.zip
Note
You must download the above sample code in order to access the 3D models used in this tutorial.
XNA Game Studio provides many methods that operate asynchronously for operations that may take longer than the desired render-cycle length.
Asynchronous methods consist of four elements:
- A Begin call that begins the asynchronous process. Begin methods return an IASyncResult object that can be used to poll for completion if a callback function is not used to detect the completion of the operation.
- An End call that ends the asynchronous process and returns objects or data requested by the Begin call. Calling the corresponding End method for each Begin method is important to prevent deadlocks and other undesirable behavior.
- An optional callback method that is called by the system when the asynchronous operation completes. This is passed to the Begin call.
- An optional, arbitrary tracking object that can be supplied to Begin to uniquely identify a particular asynchronous request. This object is part of the IASyncResult returned by Begin, and is also present in the callback method's IASyncResult parameter. Because of this, it also can be used to pass arbitrary data to the callback method when the asynchronous process completes.
The two most common methods of working with asynchronous methods are to check for completion by polling or by callback. This topic describes both methods.
Note
For exhaustive information about asynchronous methods, see Asynchronous Programming Design Patterns on MSDN.
To poll for asynchronous method completion
Call the asynchronous Begin method, and save the returned IASyncResult object to a variable that will be checked for completion.
In your update code, check IsCompleted.
When IsCompleted is true, call the End method that corresponds to the Begin method called in step 1.
The following code demonstrates the polling method.
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
this.Components.Add(new GamerServicesComponent(this));
}
IAsyncResult result;
Object stateobj;
bool GameSaveRequested = false;
GamePadState currentState;
protected override void Update(GameTime gameTime)
{
GamePadState previousState = currentState;
currentState = GamePad.GetState(PlayerIndex.One);
// Allows the default game to exit on Xbox 360 and Windows
if (currentState.Buttons.Back == ButtonState.Pressed)
this.Exit();
if ((currentState.Buttons.A == ButtonState.Pressed) &&
(previousState.Buttons.A == ButtonState.Released))
{
// Set the request flag
if ((!Guide.IsVisible) && (GameSaveRequested == false))
{
GameSaveRequested = true;
result = StorageDevice.BeginShowSelector(
PlayerIndex.One, null, null);
}
}
// If a save is pending, save as soon as the
// storage device is chosen
if ((GameSaveRequested) && (result.IsCompleted))
{
StorageDevice device = StorageDevice.EndShowSelector(result);
if (device != null && device.IsConnected)
{
DoSaveGame(device);
}
// Reset the request flag
GameSaveRequested = false;
}
base.Update(gameTime);
}
To use a callback to check for asynchronous method completion
Call the asyncronous Begin method, passing it an AsyncCallback method that will be called when the asynchronous process is completed.
AsyncCallback methods must return void, and take a single parameter: IASyncResult.
In the callback, call the End method that corresponds to the Begin method called in step 1.
The End method typically returns any data or objects requested by the Begin call.
The following code demonstrates the callback method. First, a callback method is defined.
protected void GetTypedChars(IAsyncResult r)
{
typedText = Guide.EndShowKeyboardInput(r);
}
Then, this callback is passed in when calling the Begin method.
kbResult = Guide.BeginShowKeyboardInput(PlayerIndex.One,
"Here's your Keyboard", "Type something...",
((typedText == null) ? "" : typedText),
GetTypedChars, null);