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.