I have a third party WinForms control that I need to use for visualizing and saving data as images. I don’t really need to see the form on my screen, I just need it to exist. Currently I just create a new Thread
, set it to STA and then create a Form
on the thread (and move the form off the screen because I don’t want to see it). The thread then gets blocked in a loop where it sometimes picks up items for rendering from a BlockingCollection
According to this answer I should start a message loop using Application.Run(form)
on this thread and I should also not block this thread. My code violates both of these principles.
Based on my limited testing I can’t see any issues with my approach but I lack the depth of understanding to foresee potential issues here.
private static void ProcessQueue()
{
// This function gets passed in the Thread ctor
Debug.Assert(Thread.CurrentThread.GetApartmentState() == ApartmentState.STA);
var form = new Form()
{
ShowInTaskbar = false,
Height = 800,
Width = 800,
FormBorderStyle = FormBorderStyle.None,
MaximizeBox = false,
MinimizeBox = false,
Text = "Graphics helper window"
};
var display = new MyThirdPartyActiveXDisplay();
form.Controls.Add(display);
display.Dock = DockStyle.Fill;
form.Show();
form.Top = -2000;
form.Left = -2000;
while (!SaveQueue.IsCompleted)
{
var item = SaveQueue.Take();
var image = display.render(item.value)
item.SetResult(image); // This uses a TaskCompletionSource under the hood to pass the result to the caller that added the item to the queue
}
}
What potential risks should I look for with this approach? Why is it recommended to start a message pump and not block an STAThread?