首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多线程进程更新

多线程进程更新
EN

Stack Overflow用户
提问于 2015-05-15 11:51:21
回答 3查看 1.4K关注 0票数 1

我需要显示某种形式的反馈给用户,而一个小进程(7-10秒)发生在后台。

过去,我在Windows中使用单独的线程和BackgroundWorkers没有问题,但是在WPF中很难做到这一点。

在这方面,我读过许多文章,以及如何使用WPF中的调度程序启动新线程等等。然而,当我试图使用BackgroundWorker显示等待的图像反馈形式时,它只是静止的。

我不认为这很重要,但它使用了FirstFloor (https://github.com/firstfloorsoftware/mui)的mui。

我正在尝试使用内置的ProgressRing特性(它在同一个线程中运行时没有问题,后台也没有运行其他主要任务。

添加BackgroundWorker会导致对象的跨线程访问带来异常,尽管许多博客指出WPF中的BackgroundWorks具有跨线程感知和安全运行的特性。

下面是生成我所需内容的最接近的代码。

代码语言:javascript
复制
    private async void MyTaskProcess()
    {

        await Dispatcher.BeginInvoke(DispatcherPriority.Send, new ThreadStart(() =>
        {
            try
            {
                //Update the waiting ring image
                ProgressRing.IsActive = true;
            }
            catch
            {
                ProgressRing.IsActive = false;
                MessageBox.Show("Exception Thrown");
            }
        }));


        await Dispatcher.BeginInvoke(DispatcherPriority.Background, new ThreadStart(() =>
        {
            try
            {        
                //Run the main MS Excel export function
                Export2Excel();
                ProgressRing.IsActive = false;
            }
            catch
            {
                MessageBox.Show("Exception Thrown");
            }
        }));

    }

如有任何反馈,将不胜感激。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-15 13:32:39

在现代WPF应用程序中,您这样做的方法是启动一个新的Task,您可以在其中完成这项工作;在幕后,它将在线程池线程上执行工作:

代码语言:javascript
复制
Task.Factory.StartNew(this.DoWork)

现在,在DoWork中,当InvokeAsync计数发生变化时,要报告进度,您可以返回到主线程:

代码语言:javascript
复制
void DoWork()
{
    foreach(var item in this.WorkItems)
    {
        // Do something

        // Report Progress
        ++progress
        Application.Current.Dispatcher.InvokeAsync(() => this.Progress = progress);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2015-05-15 20:29:02

添加BackgroundWorker会导致对象的跨线程访问带来异常,尽管许多博客指出WPF中的BackgroundWorks具有跨线程感知和安全运行的特性。

只要您在UI线程上创建和启动BGW,BackgroundWorker就可以很好地处理WPF。(附带说明,BGW对Windows窗体也有相同的限制)。正如其他评论者所指出的,使用BGW进行进度更新的正确方法是使用ReportProgress,而不是使用Dispatcher

但是,我建议使用更新的Task.RunIProgress<T>进行进度更新。我有一个博客帖子,它比较/对比旧的BGW进度更新和新的IProgress<T>-based进度更新。

很难说出您的代码应该是什么样子,因为您发布的代码实际上没有在后台线程上运行任何内容。特别是,如果Export2Excel必须在UI线程上运行,而这就是您所做的全部工作,那么使用BGW或Task.Run根本就没有意义,因为任何东西都不能在后台线程上运行。

票数 1
EN

Stack Overflow用户

发布于 2015-05-15 12:50:31

你可以去看我写的下面的链接,仔细阅读,我希望你能彻底解决你的问题:

WPF中的线程

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30258841

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档