代码之家  ›  专栏  ›  技术社区  ›  Jiew Meng

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

  •  1
  • Jiew Meng  · 技术社区  · 14 年前

    假设我有一个 HttpHelper 有一个 GetResponseStream() ,上载通过事件显示进度的请求数据 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
    }
    

    代码 @pastebin . GetRequestStream() 在76号线上。类本身运行良好,除了using类需要像下面这样调用它

    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线程被阻塞有关。如何重新编码类,使using类更容易/更干净地使用它,而不需要所有 _dispatcher &安培; Task 东西。

    另外,我想确定是什么导致事件/UI不更新。即使代码是同步的,它也不能运行属性changed/events,毕竟是在读/写之后?

    1 回复  |  直到 14 年前
        1
  •  2
  •   OJ.    14 年前

    你应该考虑使用 BackgroundWorker 而不是自己手工制作。使用 ReportProgress 将处理状态传递给UI线程。