سؤال

I working on an application that prints PDFs using COM and the Acrobat SDK. The app is written in C#, WPF and I am trying to figure out how to run the printing correctly on a separate thread. I have seen that a BackgroundWorker uses the thread pool and therefore cannot be set to be STA. I do know how to create a STA thread, but am unsure how I would report progress from a STA thread:

Thread thread = new Thread(PrintMethod);
thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
thread.Start(); 
thread.Join(); //Wait for the thread to end

How do I report progress to my WPF ViewModel in a STA thread created like this?

هل كانت مفيدة؟

المحلول

Actually not, you need to report progress not from but to an (already existing) STA thread, in which the UI runs.

You can achieve this either through BackgroundWorker functions (ReportProgress is delivered on the thread which started the BackgroundWorker -- this should be your UI thread), or using the UI thread's Dispatcher (usually with Dispatcher.BeginInvoke).


Edit:
For your case, the solution with BackgroundWorker won't work, as its thread is not STA. So you need to work with just usual DispatcherlInvoke:

// in UI thread:
Thread thread = new Thread(PrintMethod);
thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
thread.Start();

void PrintMethod() // runs in print thread
{
    // do something
    ReportProgress(0.5);
    // do something more
    ReportProgress(1.0);
}

void ReportProgress(double p) // runs in print thread
{
    var d = this.Dispatcher;
    d.BeginInvoke((Action)(() =>
            {
                SetProgressValue(p);
            }));
}

void SetProgressValue(double p) // runs in UI thread
{
    label.Content = string.Format("{0}% ready", p * 100.0);
}

In case your current object does not have a Dispatcher, you can take it from your UI objects or view model (if you use one).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top