Quick question: One of my forms in my winform app (c#) makes an async call to a WCF service to get some data. If the form happens to close before the callback happens, it crashes with an error about accessing a disposed object. What's the correct way to check/handle this situation? The error happens on the Invoke call to the method to update my form, but I can't drill down to the inner exception because it says the code has been optimized.
The Code:
public void RequestUserPhoto(int userID) { WCF.Service.BeginGetUserPhoto(userID, new AsyncCallback(GetUserPhotoCB), userID); }public void GetUserPhotoCB(IAsyncResult result) { var photo = WCF.Service.EndGetUserPhoto(result); int userID = (int)result.AsyncState; UpdateUserPhoto(userID, photo); } public delegate void UpdateUserPhotoDelegate(int userID, Binary photo); public void UpdateUserPhoto(int userID, Binary photo) { if (InvokeRequired) { var d = new UpdateUserPhotoDelegate(UpdateUserPhoto); Invoke(d, new object[] { userID, photo }); } else { if (photo != null) { var ms = new MemoryStream(photo.ToArray()); var bmp = new System.Drawing.Bitmap(ms); if (userID == theForm.AuthUserID) { pbMyPhoto.BackgroundImage = bmp; } else { pbPhoto.BackgroundImage = bmp; } } } }
UPDATE:
I still don't know where to go with this. What I really need here is a design pattern for making WCF async service calls from a win form that is elegant at handling form closes before the async call can return. The user is able to click the X on the form, or any form, at any time. The problem is much larger than the single example I shown above. My app actually makes hundreds of WCF calls, and I'm trying to figure out how to handle these gracefully, and in a consistent way throughout my application. For example, if I have to add a 100 lines of codes with ManualResetEvents or background workers, or mutexes, or whatever, for each WCF call just so it won't bomb my app, that's going to introduce a lot of room for error. What I need is a clean way to call a service asyncronously, and then convert it to a one-way call if the form happens to close. In other words, let the service finish running, but I don't care what the results are, and don't call the callback, because it isn't there anymore.