I've got a windows svc which is running asynchronously (I've edited the methods and their parameters to make them async), a little like: http://msdn.microsoft.com/en-us/library/ms731177.aspx
However, I call the task which I want to run asynchronously (the call to the service/server), and then update the UI (using ReportProgress() on the backgroundworker - all of this is happening in the dowork() method of a backgroundworker). However, I call the Endxxx method to get the results, but the problem is, shouldn't my code look like?
while (!asyncresult.IsCompleted) { // Do all UI updating etc here... }
// Call endXXX here.
However, this approach locks the UI. At the moment, my code is like so (and doesn't lock the UI):
IAsyncResult res = null;
try
{
res = serviceX.BeginXXX(ResultCallBack, "");
}
catch (FaultException<ManagementException> managementEx)
{
Logger.Error(managementEx.Detail.ToString());
MessageBox.Show("Could not add printer. See log.");
}
InstallBackgoundWorker.ReportProgress(90);
InstallBackgoundWorker.ReportProgress(91);
InstallBackgoundWorker.ReportProgress(93);
InstallBackgoundWorker.ReportProgress(94);
InstallBackgoundWorker.ReportProgress(95);
InstallBackgoundWorker.ReportProgress(96);
InstallBackgoundWorker.ReportProgress(97);
if (res.IsCompleted)
{
ResultCallBack(res);
}
InstallBackgoundWorker.ReportProgress(100);
Is this correct? It seems wrong to me.
I'm not certain that you're using the async pattern correctly. It should look something like this:
void Start()
{
System.IO.Stream s = ...;
byte[] buf = ...;
// start the IO.
s.BeginRead(buf, 0, buf.Length, res =>
{
// this gets called when it's finished,
// but you're in a different thread.
int len = s.EndRead(res);
// so you must call Dispatcher.Invoke
// to get back to the UI thread.
Dispatcher.Invoke((Action)delegate
{
// perform UI updates here.
});
}, null);
// the IO is started (and maybe finished) here,
// but you probably don't need to put anything here.
}
Written with Stream
because I don't know the signature of your object, but hopefully you get the idea! You need to process the completion of the operation in the callback you give it, not directly after you call the Begin method. You shouldn't need to poll the IsCompleted
property.