AB4D Forum

Full Version: can you use Ab2d.ReaderSvg library from a service ?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,
I want to use ReaderSvg to convert a svg file to xaml on the fly in a webservice something like the code below.

byte[] byteArray = Encoding.ASCII.GetBytes(svg);
using (MemoryStream stream = new MemoryStream(byteArray))
{
Ab2d.ReaderSvg svgReader = new Ab2d.ReaderSvg();
svgReader.Read(stream);

SilverlightXamlWriterSettings settings = new SilverlightXamlWriterSettings(SilverlightXamlWriterSettings.SilverlightVersionType.Silverlight_4);

string xaml = svgReader.GetXaml(settings);

return xaml;
}

As it pops up the evaluation screen on the webs server I get

The calling thread must be STA, because many UI components require this.

Is there a way to use this library without UI ?
The problem is not UI related but related to the fact that WPF only works on STA thread apartment.

A user had the same problems before and this is what he did to solve the problem:

You have to create a STA thread on the server and run it in. The exception we got when doing this is specific to framework 3.5 SP1 and have been solved in a hotfix which is available here:

https://connect.microsoft.com/VisualStud...kID=361469

Below is a small web sample of doing the STA thread. It should be
noted that using this sample you will probably get memory leaks
because Microsoft does not support using WPF object server-side. We are
doing some more WPF stuff server-side like scaling and converting
bitmap images so we have created classes to load WPF in a separate
AppDomain which then can be unloaded to avoid the memory leak issues.
This is not included in the sample.

Here is the sample. To use it just create a new web application in
visual studio (using framework 3.5), add references to
PresentationCore, PresentationFramework, WindowsBase, Ab2d.ReaderSvg
and put this in the code-behind of the default.aspx page:


Code:
protected void Page_Load(object sender, EventArgs e)
   {

     string svgFileName = @"C:\Test1.svg";
     string xamlFileName = @"C:\Test1.xaml";
     object[] threadParameter = { svgFileName, xamlFileName };

     // Enable this to see exception "The calling thread must be STA,
because many UI components require this."
     //ConvertToXAML(threadParameter);

     RunUIMethodInSTAThread(ConvertToXAML, threadParameter);
     Response.Write("DONE!");

   }

   public static void RunUIMethodInSTAThread(ParameterizedThreadStart
uiMethodToRun, object[] threadParameter)
   {
     Thread t = new Thread(uiMethodToRun);
     t.SetApartmentState(ApartmentState.STA);
     t.Start(threadParameter);

     // Wait for thread to complete
     if (!t.Join(30000))
     {
       t.Abort();
       throw new ApplicationException("UI thread aborted due to
timeout");
     }
   }

   private void ConvertToXAML(object parameter)
   {
     // Get params
     object[] parameters = (object[])parameter;
     string svgFileName = (string)parameters[0];
     string xamlFileName = (string)parameters[1];
     // Read Svg
     byte[] bytes = File.ReadAllBytes(svgFileName);
     MemoryStream svgStream = new MemoryStream(bytes);
     Viewbox importedViewbox = Ab2d.ReaderSvg.Instance.Read
(svgStream);
     UIElement innerCanvas = importedViewbox.Child;
     // Write XAML file
     using(FileStream fs = new FileStream(xamlFileName, FileMode.Create))
     {
         XamlWriter.Save(innerCanvas, fs);
     }
   }