Need Guidance on How to make Function Async/Non Blocking
Suppose I have a HttpHelper
class that has a GetResponseStream()
, that upload request data showing progress via events StatusChanged
& ProgressChanged
.
public MemoryStream GetResponseStream() {
...
Status = Statuses.Uploading; // this doesn't raise StatusChanged
// write to request stream
... // as I write to stream, ProgressChanged doesn't get raised too
Status = Statuses.Downloading; // this too
// write to response stream
... // same here
Status = Statuses.Idle; // this runs ok. Event triggered, UI updated
}
Code @pastebin. GetRequestStream()
on line 76. The class itself works fine except the using class need to call it like below
HttpHelper helper = new HttpHelper("http://localhost/uploadTest.php");
helper.AddFileHeader("test.txt", "test.txt", "text/plain", File.ReadAllBytes("./test.txt"));
helper.StatusChanged += (s, evt) =>
{
_dispatcher.Invoke(new Action(() => txtStatus.Text = helper.Status.ToString()));
if (helper.Status == HttpHelper.Statuses.Idle || helper.Status == HttpHelper.Statuses.Error)
_dispatcher.Invoke(new Action(() => progBar.IsIndeterminate = false));
if (helper.Status == HttpHelper.Statuses.Error)
_dispatcher.Invoke(new Action(() => txtStatus.Text = helper.Error.Message));
};
helper.ProgressChanged += (s, evt) =>
{
if (helper.Progress.HasValue)
_dispatcher.Invoke(new Action(() => progBar.Value = (double)helper.Progress));
else
_dispatcher.Invoke(new Action(() => progBar.IsIndetermin开发者_如何转开发ate = true));
};
Task.Factory.StartNew(() => helper.GetResponseString());
If I had called the class using
helper.GetResponseString();
Then the class itself will work, but events don't seem to be raised. I think it has to do with the UI thread being blocked. How can I at recode the class such that its easier/cleaner for the using class to use it, without all the _dispatcher
& Task
stuff.
Also, I will like to know for sure whats causing the events/UI to not update. Even if the code is synchronous, can't it run the property changed/events anyways, its after the read/write afterall?
You should look into using the BackgroundWorker instead of hand-crafting this yourself. Use ReportProgress to pass the state of processing to your UI thread.
精彩评论