There is a queuing infrastructure in Windows Workflow that facilitates communications between workflows and the outside world. Event related activities, like the HandleExternalEvent and Delay activities, provide a formalized layer of abstraction over this queuing infrastructure. You might never need to know that a queuing service exists if you can get 100% of the job done with components from the base activity library.
If you need more flexible messaging, or like Harry, want to work with a low level API, you can use the queuing service to create queues and en-queue messages for your own purposes. Before jumping in, it's worthwhile to study how the built-in activities make use of workflow queues, particularly workflow queue names.
If we look at the correlated local service example in the Windows SDK, we'll find a Parallel activity with two sequences inside. Both sequences call a CreateTask method and expect a TaskCompleted event to arrive. A local service we've implemented has to raise this TaskCompleted event, but the event isn't delivered directly to the running workflow. Instead, the workflow runtime catches the event. The workflow instance might be unloaded from memory and living as a serialized blob in a database table. The runtime will reload the proper workflow and deliver the event.
If there are multiple workflow instances active, it's easy for the runtime to find the right instance because of the InstanceId property on all incoming event arguments (local service communications might define event arguments that derive from the ExternalDataEventArgs class).
But how does the workflow know what activity is waiting for the event? This isn't hard if there is only one activity waiting for an event, but in this sample we have two activities both waiting for the same event from the same service.The secret is in the workflow queue names the individual activities create to wait for the events. If we use GetWorkflowQueueData on the workflow instance, we can inspect the queue names. A queue name in the this SDK sample will look like the following:Message Properties
What we see is that the workflow queue "name" actually contains all of the information the runtime needs to deliver events to their proper destination. The name includes the interface and event name, as well as correlation values when the associated activities have correlation tokens.
Queue names in windows Workflow are more than just friendly identifiers. As Harry pointed out, they implement IComparable and are actually a key piece to how Windows Workflow works with data exchange services.