如何使一个用户表单发布系统graphics(.net)

我使用的是VS2008,我已经设法将我自学(严重)的代码和我在互联网上find的东西放在一起,现在我已经遇到了困难。 我看了一下,我不知道如何解决这个问题。

当有人按下一个button时,我会向两个模块发送数据,第一个将数据网格放置在数据网格的顶部并旋转图像,同时等待第二个线程将数据保存到Excel。 我得到的问题是当它运行代码时,到达'Me.PictureBox4.Image = DirectCast(BM_out.Clone(),System.Drawing.Image)'这一行'错误信息'在别处使用的对象'。

Public MoveByCalc As Double Public ReturnStack As New System.Collections.Generic.Stack(Of Integer) Public BM_In As New Bitmap(My.Resources.Fan) Public Wid As Single = BM_In.Width Public Hgt As Single = BM_In.Height Public Cx As Single = Wid / 2 Public Cy As Single = Hgt / 2 Public TimeElapsed As Single = 1 Public EndThread As String = "No" Public X As Integer Public BS As New BindingSource Public AutoNum As Integer Public CellConnection As New OleDbConnection Public DB1Connection As New OleDbConnection Public DB2Connection As New OleDbConnection Public OldScrollValue As Integer : Public Direction As Integer Public objDataAdapter As New OleDbDataAdapter() Public objDataSet As New DataSet() Public objDataAdapterDB1 As New OleDbDataAdapter() Public objDataSetDB1 As New DataSet() Public objDataAdapterDB2 As New OleDbDataAdapter() Public objDataSetDB2 As New DataSet() Public DBCount As String Public LoadError As Integer Public TempString As String Public DisableSearch As Integer Public DataGridTop As Double Public DataGridHeight As Double Public DataGridBottom As Double Public DBLoc As Integer Public ButtonSelectedColour As Color = Color.FromArgb(253, 183, 89) Public Sub SaveButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CloseButton.Click PictureBox4.Visible = True PictureBox4.Top = DataGridView1.Top : PictureBox4.Left = DataGridView1.Left PictureBox4.Height = DataGridView1.Height : PictureBox4.Width = DataGridView1.Width EndThread = "No" DataGridView1.DataSource = objDataSet.Tables(0).DefaultView Dim T As Thread T = New Thread(AddressOf Me.FanSpin) T.Start() Dim S As Thread S = New Thread(AddressOf Me.SaveData) S.Start() End Sub Private Sub FanSpin() Dim KeepRunning As Boolean = True 'On Error GoTo EndThread While KeepRunning TimeElapsed = TimeElapsed + 1 Dim Corners As Point() = { _ New Point(0, 0), _ New Point(Wid, 0), _ New Point(0, Hgt), _ New Point(Wid, Hgt)} Dim I As Long For I = 0 To 3 Corners(I).X -= Cx Corners(I).Y -= Cy Next I Dim theta As Single = Single.Parse(-TimeElapsed) * PI / 180.0 Dim X As Single Dim Y As Single For I = 0 To 3 X = Corners(I).X Y = Corners(I).Y Corners(I).X = X * Cos(theta) + Y * Sin(theta) Corners(I).Y = -X * Sin(theta) + Y * Cos(theta) Next I Dim xmin As Single = Corners(0).X Dim ymin As Single = Corners(0).Y For I = 1 To 3 If xmin > Corners(I).X Then xmin = Corners(I).X If ymin > Corners(I).Y Then ymin = Corners(I).Y Next I For I = 0 To 3 Corners(I).X -= xmin Corners(I).Y -= ymin Next I Dim BM_out As Bitmap = New Bitmap(CInt(-2 * xmin), CInt(-2 * ymin)) Dim gr_out As Graphics = Graphics.FromImage(BM_out) ReDim Preserve Corners(2) SyncLock BM_In gr_out.DrawImage(BM_In, Corners) End SyncLock If BM_out IsNot Nothing Then SyncLock BM_out Me.PictureBox4.Image = DirectCast(BM_out.Clone(), System.Drawing.Image) End SyncLock End If If EndThread = "Yes" Then KeepRunning = False End If End While EndThread: PictureBox4.Image = Nothing If Me.PictureBox4.InvokeRequired Then PictureBox4.Invoke(New Action(AddressOf PictureBox4.Hide)) Else Me.PictureBox4.Visible = False End If End Sub Public Sub DataBindToDataGrid() Select Case ReturnStack.Peek() Case 1 DataGridView1.DataSource = objDataSetDB1.Tables(0).DefaultView Case 2 DataGridView1.DataSource = objDataSetDB2.Tables(0).DefaultView End Select End Sub Private Sub SaveData() Dim CallDataBindToDataGrid As New MethodInvoker(AddressOf Me.DataBindToDataGrid) Dim XLApp As New Excel.Application Dim Wb As Excel.Workbook Dim Ws As Excel.Worksheet Dim XlRange As Excel.Range XLApp = New Excel.Application Wb = XLApp.Workbooks.Open(My.Settings.Database3C) Ws = Wb.Worksheets("Data") Ws.Activate() Ws.Unprotect() XlRange = Ws.Range("A5", "V100") XlRange.ClearContents() XlRange = Ws.Range("A5") Dim Count As Integer = 0 For Count = 0 To 49 XlRange.Value = DataGridView1.Rows(Count).Cells(0).Value XlRange.Offset(0, 1).Value = DataGridView1.Rows(Count).Cells(1).Value.ToString XlRange.Offset(0, 2).Value = DataGridView1.Rows(Count).Cells(2).Value.ToString XlRange.Offset(0, 3).Value = DataGridView1.Rows(Count).Cells(3).Value.ToString XlRange.Offset(0, 4).Value = DataGridView1.Rows(Count).Cells(4).Value.ToString XlRange.Offset(0, 5).Value = DataGridView1.Rows(Count).Cells(5).Value.ToString XlRange.Offset(0, 6).Value = DataGridView1.Rows(Count).Cells(6).Value.ToString XlRange.Offset(0, 7).Value = DataGridView1.Rows(Count).Cells(7).Value.ToString XlRange.Offset(0, 8).Value = DataGridView1.Rows(Count).Cells(8).Value.ToString XlRange.Offset(0, 9).Value = DataGridView1.Rows(Count).Cells(9).Value.ToString XlRange.Offset(0, 10).Value = DataGridView1.Rows(Count).Cells(10).Value.ToString XlRange.Offset(0, 11).Value = DataGridView1.Rows(Count).Cells(11).Value.ToString XlRange.Offset(0, 12).Value = DataGridView1.Rows(Count).Cells(12).Value.ToString XlRange.Offset(0, 13).Value = DataGridView1.Rows(Count).Cells(13).Value.ToString XlRange.Offset(0, 14).Value = DataGridView1.Rows(Count).Cells(14).Value.ToString XlRange.Offset(0, 15).Value = DataGridView1.Rows(Count).Cells(15).Value.ToString XlRange.Offset(0, 16).Value = DataGridView1.Rows(Count).Cells(16).Value.ToString XlRange.Offset(0, 17).Value = DataGridView1.Rows(Count).Cells(17).Value.ToString XlRange.Offset(0, 18).Value = DataGridView1.Rows(Count).Cells(18).Value.ToString XlRange.Offset(0, 19).Value = DataGridView1.Rows(Count).Cells(19).Value.ToString XlRange.Offset(0, 20).Value = DataGridView1.Rows(Count).Cells(20).Value.ToString XlRange.Offset(0, 21).Value = DataGridView1.Rows(Count).Cells(21).Value.ToString XlRange.Offset(0, 22).Value = DataGridView1.Rows(Count).Cells(23).Value.ToString 'DB Log numbers XlRange = XlRange.Offset(1, 0) Next Count XLApp.DisplayAlerts = False Wb.Save() Wb.Close() Wb = Nothing ReturnStack.Push(1) If My.Settings.Database1 <> "" Then Me.BeginInvoke(CallDataBindToDataGrid) Wb = XLApp.Workbooks.Open(My.Settings.Database1) GoTo SaveData End If ReturnLabel1: ReturnStack.Push(2) If My.Settings.Database2 <> "" Then Me.BeginInvoke(CallDataBindToDataGrid) Wb = XLApp.Workbooks.Open(My.Settings.Database2) GoTo SaveData End If ReturnLabel2: SaveData: Ws = Wb.Worksheets("Analysis") Ws.Activate() Ws.Unprotect() XlRange = Ws.Range("A10", "AO2009") XlRange.ClearContents() XlRange = Ws.Range("A10") Dim I As Integer Dim J As Integer For I = 0 To DataGridView1.RowCount - 2 If DataGridView1.Rows(I).Cells(1).Value.ToString <> "" Then For J = 0 To DataGridView1.ColumnCount - 1 Ws.Cells(I + 10, J + 1) = DataGridView1(J, I).Value.ToString() Next End If Next XLApp.DisplayAlerts = False Wb.Save() Wb.Close() Wb = Nothing Select Case ReturnStack.Peek() Case 1 : GoTo ReturnLabel1 Case 2 : GoTo ReturnLabel2 End Select EndSub101: XLApp.Quit() XLApp = Nothing GC.Collect() GC.WaitForPendingFinalizers() EndThread = "Yes" End Sub 

当我改变datagridview的数据源的时候,我把问题缩小了(我认为)到系统不释放graphics(releasehdc?)。 我认为这是事实,因为它在我不改变数据源的时候起作用,它实际上开始工作在它的当前状态,但是一半停下来! 我需要更改数据源,以便将不同的数据集保存到不同的Excel文件中。

我知道我不应该在线程中调用graphics,并像这样交叉线程(这是唯一的方式,我可以得到它的工作…sorting),但任何人可以提供解决这个错误的帮助将不胜感激。

谢谢Paul