@ Anant heh, I deleted the comment because, at a second glance, I thought I was reading the code incorrectly. Generally speaking, when connecting to a web service, you should always treat the call as asynchronous, because you can deal with excessive lag that blocks any thread (usually a GUI thread). This is compounded if you need to make multiple WCF calls for a single GUI action. It also gets worse, because your WCF interface is written as an asynchronous call, and then it lies and works synchronously anyway. A definite reason for future confusion.
Therefore, I believe that it is best to deal with an asynchronous model, but at least you can do type checking / casting / return processing in your WCF call. I did something similar, but instead of using synchronous calls, I will still use callbacks, but I will have an IAsyncResult handler in the WCF call, which will then pass it to the expected type and return it to the user.
public void GetEmployee(int id, Action<Employee> getEmployeeCompletedHandler) { Task<Employee> t = new Task<Employee>(()=>client.GetEmployee(id)); t.Start(); t.ContinueWith(task=> { if (getEmployeeCompletedHandler != null) getEmployeeCompletedHandler(t1.Result); }); }
What makes your typical use:
sa.GetEmployee(1673, result => this.Employee = result);
If you really want to maintain a synchronous model, you can move the work to a background thread (but it will still be โasynchronousโ in terms of GUI). At this point, you can also use your GetEmployee method synchronously and return a value. Thus, it is obvious to the API consumer that there is no asynchronous operation:
public Employee GetEmployee(int id) { Task<Employee> t = new Task<Employee>(()=>client.GetEmployee(id)); t.Start(); try { t.Wait(); } catch (AggregateException ex) { throw ex.Flatten(); } return t.Result; }
Then your calling code might look like this:
//spawn a background thread to prevent the GUI from freezing BackgroundThread.Spawn(() => { this.Employee = sa.GetEmployee(1673); });
Note. BackgroundThread is a custom class that you can create to create or spawn a background thread. I will leave this implementation detail for you, but I believe that it is best to have a managed wrapper for stream processing, because it makes using a lot easier and an abstract of the implementation details (using a stream stream? New stream? BackgroundWorker? Who cares!)
Just notice, I have not tried using WCF calls synchronously, which I just posted above (I stick with a complete asynchronous model like my first code example), so I think this will work. (I still do not recommend doing it this way!)