Solution:2

Solution:3

Let's say that you are performing a search that will result in a List<Customer> object. One rather straight-forward and simple approach is then to raise an event when the search is done, using a special EventArgs class carrying the result:

// the parameter is there to conform to the signature of the WaitDelegate // used when invoking the method using the ThreadPool public void Search(object state) { List<Customer> result = new List<Customer>(); // perform the search, populate the result list // call a method to raise the event OnSearchFinished(new CustomerSearchEventArgs(result)); } protected void OnSearchFinished(CustomerSearchEventArgs e) { EventHandler<CustomerSearchEventArgs> searchFinished = this.SearchFinished; if (searchFinished != null) { searchFinished(this, e); } }