从Windows服务中的WPF控件生成PNG

时间:2018-03-13 11:17:23

标签: c# wpf windows service controls

由于一项相当奇怪的任务,我想知道是否有可能创建一个Windows服务,每隔x秒我们就可以创建一个System.Windows.Control的PNG并将其写入磁盘。

目前,此流程是通过每个用户的WPF应用程序处理的。该过程工作正常,但渲染速度很慢(控件很大且很复杂),每次都需要生成几个不同的版本。考虑到这一点,我开始想知道这是否可以在服务器端处理。

因此,举个例子,假设我们有一个包含以下文件的目录:

  • 测试1.txt
  • 测试2.txt
  • 测试3.txt

每隔5秒,我想获取每个文件的名称,生成一个以文件名作为内容的控件,并渲染为PNG。

到目前为止我的尝试:

  • 使用定时器的服务:即使[STAThread]到处都贴满了“调用线程必须是STA”失败
  • DispatcherTimer:永远不会打勾,因为没有UI线程导致它勾选
  • 使用Timer和Application.Current.Dispatcher.Invoke进行的服务:由于调用中有一个或两个空对象,因此会崩溃。

有谁知道这是否可能?

1 个答案:

答案 0 :(得分:0)

我不确定您是否可以从服务创建新的Windows。但我可以解决你的计时器问题。

如果要创建其中一个定时器,通常需要在STAT-Thread中执行。Why is STAThread required?

Thread timer = new Thread(() =>
{
    while (true)
    {
        //do stuff...

        Thread.Sleep(5000); //wait 5 seconds
    }
 });
 timer.SetApartmentState(ApartmentState.STA); //creates a new Thread for UIs
 timer.IsBackground = true; //if you main Thread exits this will also shutdown.
 timer.Start();

如果您不想使用Lambda

private void MyTimerMethode()
{
    while (true)
    {
        // do stuff...

        Thread.Sleep(5000); //wait 5 seconds
    }
}


    Thread timer = new Thread(MyTimerMethode);
    timer.SetApartmentState(ApartmentState.STA); //creates a new Thread for UIs
    timer.IsBackground = true;
    timer.Start();

如果要杀死它,可以使用

timer.Abort();

但我建议使用像bool isAlive = true;这样的字段并将其用作while循环条件。现在,如果你想结束它,你可以结束它而不会杀死它并抛出任何例外。

这是我在快速谷歌搜索后将控件渲染为图像后发现的。 How to render a WPF UserControl to a bitmap without creating a window

修改 我尝试使用“如何在不创建窗口的情况下将WPF UserControl渲染到位图”中的代码,它甚至可以在服务中使用。