DispatcherHelper to thread

本文关键字:thread to DispatcherHelper | 更新日期: 2023-09-27 18:09:37

我有一个应用程序,它使用1个主窗口,而这个窗口又有5个UserControls,它们是使用Ribbon控件创建的。

在一个用户控件上,我启动了一个线程:

if (AmtMembersWithEmail > 0)
{
    DispatcherHelper.UIDispatcher.Invoke(new Action(() =>
    {
        max = 100;
        Messenger.Default.Send<ShowProgressWindowMessage>(
                              new ShowProgressWindowMessage(this));
        Progress = 0;
        Thread.Sleep(1000);                               
    }));

所以这个线程启动并向主窗口报告进度,在此期间,当线程执行时,用户不能访问控件或在应用程序中做任何其他事情,从读取调度程序上看,这是正常的,因为它必须使用单个UIThread,允许用户与UI上的控件交互。(顺便说一下,使用Galasoft MVVM灯!)

显示报告进度的窗口有一个命令,它绑定到我的视图模型中的中继命令:

从XAML进度窗口提取如下:
<tk:LoadingAnimation Grid.Row="0" DataContext="{Binding}"/>        
<ContentControl Visibility="{Binding CanBeAborted, 
                Converter={StaticResource VisibilityConverter}}" >
    <Hyperlink Command="{Binding AbortCommand}">cancel</Hyperlink>
</ContentControl>

是否有任何方法可以使用调度程序来允许线程在后台运行?或者用户只需要等待操作完成?

要添加,线程实际上正在做的工作是循环客户数据,创建附件(发票)并为每个客户创建一个电子邮件对象,然后最后循环新的电子邮件集合并将每个电子邮件单独发送给客户…

任何帮助将不胜感激....

DispatcherHelper to thread

我不完全清楚你是否有你的处理逻辑在用户控制(即代码背后),或在你的ViewModel。如果它在你的ViewModel中,那么我认为你在正确的轨道上。

不使用dispatcher,我建议旋转一个BackgroundWorker:

    public void DoWork()
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += (sender, e) =>
        {
            //Processing Logic here
        };
        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Work_Completed);
        worker.RunWorkerAsync();
    }
    void Work_Completed(object sender, RunWorkerCompletedEventArgs e)
    {
    }

这不会在UI线程上运行,因此你的用户控件应该是响应的。此外,正如建议的那样,不要终止线程。您的Abort逻辑应该优雅地退出处理逻辑内部的循环,清理它使用的资源并执行您需要完成的任何撤消工作。