可以使用BackgroundWorker的ReportProgress来做其他事情吗?

发布于 2024-09-13 23:44:40 字数 1394 浏览 6 评论 0原文

我正在使用 MVVM 方法编写 WPF 应用程序。在我的 ViewModel 中,我有一个 ObservableCollection。我的应用程序需要定期检查新消息,如果有的话,需要将它们添加到 ObservableCollection 中。

如果我尝试添加到 DoWork 中的 ObservableCollection,由于线程同步问题,它不起作用。看起来在 UI 线程上实现这一点的最简单方法是执行 ReportProgress() 并从那里更新集合。

我的问题是:从哲学和技术上讲,是否可以从 ReportProgress 处理程序更新 UI,即使“根据法律规定”我实际上并没有报告进度。

有没有更合理的方法来做到这一点?

* 编辑:代码使用 Dispatcher Timer *

ViewModel

class MyViewModel
{
    public ObservableCollection<string> MyList { get; set; }

    public MyViewModel()
    {
        MyList = new ObservableCollection<string>();
    }
}

“teh codez” - 只是一个示例,而不是我的实际应用程序代码。

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {

        MyViewModel mvm = new MyViewModel();
        this.DataContext = mvm;

        DispatcherTimer mytimer = new DispatcherTimer();
        mytimer.Interval = TimeSpan.FromSeconds(5.0);
        mytimer.Tick += new EventHandler(mytimer_Tick);

        mytimer.Start();


    }

    void mytimer_Tick(object sender, EventArgs e)
    {
        ((DispatcherTimer)sender).Stop();

        MyViewModel mvm = this.DataContext as MyViewModel;
        mvm.MyList.Insert(0, DateTime.Now.ToLongTimeString());

        ((DispatcherTimer)sender).Start();
    }

这看起来可以很好地满足我的需要,并且不会给我带来我不会使用的额外包袱(例如取消、workercompleted 等)。

I'm writing a WPF app using an MVVM approach. In my ViewModel, I have an ObservableCollection. Periodically, my app needs to check for new messages, and, if there are any, it needs to add them to the ObservableCollection.

If I try to add to the ObservableCollection in the DoWork, it doesn't work because of thread synchronization issues. It looks like the easiest way to get this to happen on the UI thread is to do a ReportProgress() and update the collection from there.

My question is: Philosophically and technically, is it ok to update the UI from the ReportProgress handler, even though "by the letter of the law" I'm not actually reporting progress.

Is there a more sound way to do this?

* EDIT: Code works using Dispatcher Timer *

ViewModel

class MyViewModel
{
    public ObservableCollection<string> MyList { get; set; }

    public MyViewModel()
    {
        MyList = new ObservableCollection<string>();
    }
}

"teh codez" - just a sample, not my actual application code.

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {

        MyViewModel mvm = new MyViewModel();
        this.DataContext = mvm;

        DispatcherTimer mytimer = new DispatcherTimer();
        mytimer.Interval = TimeSpan.FromSeconds(5.0);
        mytimer.Tick += new EventHandler(mytimer_Tick);

        mytimer.Start();


    }

    void mytimer_Tick(object sender, EventArgs e)
    {
        ((DispatcherTimer)sender).Stop();

        MyViewModel mvm = this.DataContext as MyViewModel;
        mvm.MyList.Insert(0, DateTime.Now.ToLongTimeString());

        ((DispatcherTimer)sender).Start();
    }

This looks like it will work well for what I need, and doesn't give me additional baggage that I'm not going to use (e.g. cancel, workercompleted, etc.).

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

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

发布评论

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

评论(3

抱着落日 2024-09-20 23:44:40

如果您在应用程序中实现轮询类型的功能,那么使用按一定时间间隔触发的 DispatcherTimer 可能更有意义,而不是在 BackgroundWorker 内部不断循环。

http://msdn.microsoft.com/en-我们/library/system.windows.threading.dispatchertimer.aspx

If you're implementing polling-type functionality in your app, it probably makes more sense to use a DispatcherTimer that fires at an interval instead of constantly looping inside of the BackgroundWorker.

http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer.aspx

情话墙 2024-09-20 23:44:40

当然。这就是 EventArgs 的 UserState 的设计目的。

使用BackgroundWorker 的原因是为了简化多线程。否则,您必须执行类似 Invoke(或 BeginInvoke)之类的操作来处理 BackgroundWorker 正在执行的相同操作。

Sure. That's what the UserState of the EventArgs is designed for.

The reason for the BackgroundWorker is to simplify multithreading. Otherwise, you'd have to do something like Invoke (or BeginInvoke) to handle the same thing the BackgroundWorker is being used for.

咋地 2024-09-20 23:44:40

我不会这样做

它“感觉”像是将来会导致问题的东西(也许当其他人尝试从现在开始添加功能时,也许当此代码升级或移植到具有稍微不同的 ReportProgress 实现的环境时)。

我只会使用 Dispatcher.BeginInvoke (我也尽量避免使用 Invoke,因为它会让一个线程等待另一个线程,并首先降低使用多线程的效率)。

但是,在某些地方,仅使用 ReportProgress 就是正确的选择,您需要自己决定什么是最适合您的具体情况的(我最讨厌的事情是更重视“最佳实践”或“架构”,而不是产生实际的工作)软件)

I wouldn't do it

It "feels" like something that will cause problems in the future (maybe when someone else tries to add features years from now, maybe when this code is upgraded or ported to an environment with slightly different ReportProgress implementation).

I would just use Dispatcher.BeginInvoke (I also try to avoid using Invoke because it makes one thread wait for the other and reduce the efficiency of using multi-threading in the first place).

But, there are places where just using ReportProgress is the right choice, you need to decide for yourself what is the best thing for your specific situation (the thing I hate most is valuing "best practices" or "architecture" more then producing actual working software)

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