Click here to Skip to main content
15,878,871 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
See more:
Hi guys,

I'm having this little problem on my function. I call a bgworker to dowork. Inside dowork, I will call a function to do another 3 separate function, but it's stop at first function with message as my question. Please take a look at my code and see which part that I missed. I already search for it and already try to do as they did, but no luck. So I'm giving the original code:-

VB
Private Sub btn_selectxps_Click(sender As System.Object, e As System.EventArgs) Handles btn_selectxps.Click
        Try
            MessageBox.Show("Please wait while file been retrieve from selected path.")
            If bgworker_select.IsBusy <> True Then
                ' Start the asynchronous operation.
                bgworker_select.WorkerSupportsCancellation = True
                bgworker_select.WorkerReportsProgress = True
                bgworker_select.RunWorkerAsync()
            End If
        Catch ex As Exception
            strInfoMsg = "Oops! Something is wrong with load xps file." & vbCrLf & "Ex:- " & ex.Message
            MessageBox.Show(strInfoMsg & vbCrLf & "Err: " & ex.Message)
        End Try
    End If
End Sub


VB
Private Sub bgworker_select_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgworker_select.DoWork
    Try
        Dim workIsCompleted As Boolean = False
        While (Not bgworker_select.CancellationPending) AndAlso (Not workIsCompleted)
            Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
            If worker.CancellationPending = True Then
                MessageBox.Show("Saving is cancel by user")
                e.Cancel = True
                Return
            End If
            If DoSelectWork() Then
                MessageBox.Show("Retrieve complete")
            End If
            workIsCompleted = True
        End While
    Catch ex As Exception
        MessageBox.Show("Save failed. Ex-" & ex.ToString)
    End Try
End Sub


VB
Private Function DoSelectWork() As Boolean
    Try
        xpsToBmp()
        StreamBitmapToByte()
        ViewXPS()
    Catch ex As Exception
        strInfoMsg = "Oops! Something is wrong with DoSelectWork." & vbCrLf & "Ex:- " & ex.Message
        MessageBox.Show(strInfoMsg & vbCrLf & "Err: " & ex.Message)
    End Try
End Function


VB
Public Sub xpsToBmp()
    Dim xps As New XpsDocument(txt_xpspath.Text, System.IO.FileAccess.Read)
    Dim sequence As FixedDocumentSequence = xps.GetFixedDocumentSequence() ''//////////Exception in here
    Dim strName As String
    Try
        For pageCount As Integer = 0 To sequence.DocumentPaginator.PageCount - 1
            Dim page As DocumentPage = sequence.DocumentPaginator.GetPage(pageCount)
            Dim toBitmap As New RenderTargetBitmap(CInt(Fix(page.Size.Width)), CInt(Fix(page.Size.Height)), 96, 96, System.Windows.Media.PixelFormats.Default)
            toBitmap.Render(page.Visual)
            Dim bmpEncoder As BitmapEncoder = New BmpBitmapEncoder()
            bmpEncoder.Frames.Add(BitmapFrame.Create(toBitmap))
            strName = pageCount.ToString("0000")
            Dim fStream As New FileStream(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) & "\XPS\xps_" & strName & ".bmp", FileMode.Create, FileAccess.Write)
            bmpEncoder.Save(fStream)
            fStream.Close()
        Next pageCount
    Catch ex As Exception
        strInfoMsg = "Oops! Something is wrong with comvert xps to bmp." & vbCrLf & "Ex:- " & ex.Message
        MessageBox.Show(strInfoMsg & vbCrLf & "Err: " & ex.Message)
    End Try
End Sub


What I'm missing here?
Posted
Comments
Sergey Alexandrovich Kryukov 6-Feb-15 3:41am    
What the title of the question means? Where did you read these words? WinForms perfectly works in both STA and MTA.
—SA
Luiey Ichigo 9-Feb-15 1:35am    
Hello sir, this word appear when I debug the code within my solutions and it stop at comment on xpsToBmp() function.
Sergey Alexandrovich Kryukov 9-Feb-15 3:15am    
All right, this is all that matters. The solution is ready please see.
—SA
Philippe Mori 6-Feb-15 12:46pm    
On which line the exception occurs? The message is quite explicit. Some operations cannot be done on the background thread.
Luiey Ichigo 9-Feb-15 1:37am    
Hello Philippe, the exception occur at Dim sequence As FixedDocumentSequence = xps.GetFixedDocumentSequence() ''//////////Exception in here on Public Sub xpsToBmp(). If I skip using background worker and direct to Private Function DoSelectWork() As Boolean, ssytem able to convert xps file to bitmap but my application will be freeze until all page is convert to bitmap. That's why I try to put it on background worker. But it stop with exception as per title.

1 solution

Thank you for the clarification. You have to change the apartment model of the thread calling the method causing this problem. You need to change it to STA as required; there is no another way. There are at least two ways of doing that.

You cannot do it on your background worker. I actually almost never use BackgroundWalker, by this and a number of other reasons. I would create a "permanent" thread which I would reuse during the lifetime of the application.
C#
Thread myThread = new Thread(threadMethod);
myThread.SetApartmentState(ApartmentState.STA);
// ...
myThread.Start();

As you can see, apartment thread is set before the thread start, in some other thread. This is also a must: a thread cannot change its own apartment state. See also my past answer on working with such threads and their reuse:
Making Code Thread Safe[^],
Running exactly one job/thread/process in webservice that will never get terminated (asp.net)[^],
How to pass ref parameter to the thread[^],
Change parameters of thread (producer) after it is started[^],
MultiThreading in C#[^].

Another way is this, you can define the apartment model of your application to STA. As this is a System.Windows.Forms application, in can work with any apartment model (and WPF can work only with STA, so you can use any of them). This is done by setting the usual attribute for the entry-point method:
C#
[System.STAThread]
static void Main(string[] args) {
    // ...
}


Please see:
https://msdn.microsoft.com/en-us/library/system.stathreadattribute%28v=vs.110%29.aspx[^],
https://msdn.microsoft.com/en-us/library/system.mtathreadattribute(v=vs.110).aspx[^].

Note, "single-threaded apartment" absolutely does not mean impossibility of working with multiple threads. These names are just confusing. For understanding background, please see:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms693344.aspx[^],
https://msdn.microsoft.com/en-us/library/windows/desktop/ms680112.aspx[^],
https://msdn.microsoft.com/en-us/library/windows/desktop/ms693421.aspx[^].

—SA
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900