需要有关如何使函数异步/非阻塞的指导

发布于 2024-10-04 01:41:50 字数 1984 浏览 0 评论 0原文

假设我有一个 HttpHelper 类,它有一个 GetResponseStream(),上传请求数据通过事件 StatusChangedStatusChanged 显示进度。 进度更改

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
}

代码@pastebin。第 76 行的 GetRequestStream()。类本身工作正常,除了使用类需要像下面这样调用它

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.IsIndeterminate = true));
};
Task.Factory.StartNew(() => helper.GetResponseString());

如果我使用类调用了该类

helper.GetResponseString();

,那么该类本身将工作,但事件似乎不起作用被提高。我认为这与 UI 线程被阻塞有关。我如何重新编码该类,以便使用类更容易/更干净地使用它,而不需要所有 _dispatcher & 任务的东西。

另外,我想确定是什么导致事件/用户界面不更新。即使代码是同步的,它也不能在读/写之后运行属性更改/事件吗?

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.IsIndeterminate = 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无敌元气妹 2024-10-11 01:41:50

您应该考虑使用 BackgroundWorker 而不是手动自己制作这个。使用 ReportProgress 将处理状态传递到 UI 线程。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文