Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Πρόβλημα με SaveFileDialog από Async Form [VB.NET 2010]

Îåêßíçóå áðü ôï ìÝëïò AlKiS. Τελευταία δημοσίευση από το μέλος AlKiS στις 06-08-2012, 14:39. Υπάρχουν 6 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  23-07-2012, 13:46 70962

    Πρόβλημα με SaveFileDialog από Async Form [VB.NET 2010]

    Hello all :)

    Θα χρειαστώ τη βοήθειά σας για μία ακόμη φορά :Ρ


    Έχω ένα πρόγραμμα, του οποίου ένα κουμπί εμφανίζει μια φόρμα που βγάζει στατιστικές πληροφορίες/Reports.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
        Private Async Sub btnTodaysZStat_Click(sender As System.Object, e As System.EventArgs) Handles btnStatZToday.Click
            pbStatZToday.Visible = True
            StatStatZTodayFormsOpen += 1
            lblStatZToday.Text = CStr(StatStatZTodayFormsOpen)
            lblStatZToday.Visible = True
    
            Await TaskEx.Run(
                Sub()
                    Dim TodaySelector As New frmZStatisticsSelector
                    With TodaySelector
                        .chkZTimePeriod.Checked = True
                        .dtZFromDate.Value = Today.Date
                        .dtZToDate.Value = Today.Date
                        .Opacity = 0
                        .AutoAction = "Today Database"
                        .PreventFormFromClosing = True
                        .ShowInTaskbar = False
                        .ShowDialog()
                    End With
                End Sub)
    
            StatStatZTodayFormsOpen -= 1
            lblStatZToday.Text = CStr(StatStatZTodayFormsOpen)
            If StatStatZTodayFormsOpen <= 0 Then
                lblStatZToday.Visible = False
                pbStatZToday.Visible = False
            End If
        End Sub


    Η φόρμα  frmZStatisticsSelector  που είναι στη μεταβλητή TodaySelector τώρα έχει ανοίξει ασύγχρονα, οπότε όσες πράξεις κι αν κάνει μέχρι να τελειώσει, δεν θα επηρεάσει την κυρίως φόρμα.

    Όταν κάνει λοιπόν όλες τις πράξεις, θα εμφανίσει μια φόρμα η οποία έχει μόνο ένα data grid view πάνω της και δείχνει τα δεδομένα που της έβαλε η " TodaySelector " (κάπως έτσι: )


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
          Dim frmNewSheet As New frmZStatisticsSheet
    
                If File.Exists(DataBaseFile) Then
                    Call ConnectToDatabasesAndLoadTables()
    
                    If ProdsRowCount > 0 Then
                        Call LoadZTodayMainVariables()
                        Call ApplyGeneralInfo()
                        Call CalcPerZNumPerVAT()
                        Call CalcPerPaymentMethod_Horiz()
                        Call CalcPerVATPerServer()
                        Call CalcDiscountDelRet()
                        AddRows(1)
                        frmNewSheet.Show()
    
                    Else
                        MsgBox(StrLanguage(42), MsgBoxStyle.Information)    'No Orders match your criteria
                    End If
    
                Else
                    MsgBox(StrLanguage(35) & DataBaseFile & StrLanguage(37) & vbCrLf & StrLanguage(62), MsgBoxStyle.Critical) 'file cannot be found! Please specify another path to the database path
                    frmSettings.Show()
                    Me.Close()
                End If

    (Ναί, ξέρω ότι δεν χρειάζεται να γράφω "call", όμως μου αρέσει γιατί βλέπω ότι καλώ κάτι, μην κολλήσουμε εκεί plz)

    Όλα γίνονται τέλεια! Δουλεύουν χωρίς lag, μέχρι και το PrintForm του Sheet (τελευταίας φόρμας, αυτής με μόνο το DataGridView) δουλεύει.
    Έχω γράψει επίσης ένα sub που μετατρέπει το DGV σε Comma Separated Values format (.csv). Άμα το καλέσω δουλεύει κι αυτό.

    Όμως όταν πατάω να κάνει save as, δλδ να διαλέξει ο χρήστης σε ποια μεριά να σωθεί το αρχείο, μου βγάζει πρόβλημα στο .ShowDialog του SaveFileDialog.

    Το πρόβλημα είναι:

    1
    2
    3
    4
     
    System.Threading.ThreadStateException: Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it. This exception is only raised if a debugger is attached to the process.
       at System.Windows.Forms.FileDialog.RunDialog(IntPtr hWndOwner)
       at System.Windows.Forms.CommonDialog.ShowDialog(IWin32Window owner)
       at System.Windows.Forms.CommonDialog.ShowDialog()


    Το SaveAs είναι το εξής:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
        Private Sub SaveAs()
            Try
                sfdExport.FileName = ""
                sfdExport.InitialDirectory = strDataDir
                sfdExport.DefaultExt = ".csv"
                sfdExport.FileName = DefaultSaveFileName & sfdExport.DefaultExt  'Today's Statistics or something similar
                sfdExport.Filter = strLanguage(4) & "|*.csv|All Files|*.*"  'Comma-Separated Values Files
                Dim SaveDialogResult As DialogResult = sfdExport.ShowDialog()
                If SaveDialogResult = Windows.Forms.DialogResult.OK Then
                    Dim Success As Boolean = Save_dgv_To_csv(sfdExport.FileName, dgvZStat)
                    If Success Then
                        MsgBox(strLanguage(2) & sfdExport.FileName, MsgBoxStyle.Information) 'The file has been successfully saved.
                    End If
                End If
    
    
            Catch ex As Exception
                MsgBox(ex.ToString)
                CreateCrushFile(ex.ToString)
            End Try
        End Sub


    τη μετατροπή σε csv την κάνω έτσι:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
        Public Function Save_dgv_To_csv(ByVal FileName As String, DataGrid As DataGridView, Optional ByVal IncludeColumnNames As Boolean = False, Optional LastSaveFile As String = "") As Boolean
            Try
                Dim ExportationText As String = String.Empty
    
                If IncludeColumnNames Then
                    For i As Integer = 0 To DataGrid.ColumnCount - 1
                        ExportationText &= """" & DataGrid.Columns(i).HeaderText & ""","
                    Next
                End If
    
                For j = 0 To DataGrid.RowCount - 2
                    ExportationText &= vbCrLf
                    Dim CurrentLine As String = ""
                    For i = 0 To DataGrid.ColumnCount - 1
                        If IsNumeric(DataGrid.Rows(j).Cells(i).Value) Then
                            CurrentLine &= """" & DataGrid.Rows(j).Cells(i).Value.ToString.Replace(",", ".") & ""","
                        Else
                            If DataGrid.Rows(j).Cells(i).Value IsNot Nothing Then
                                CurrentLine &= """" & DataGrid.Rows(j).Cells(i).Value.ToString & ""","
                            Else
                                CurrentLine &= """" & ""","
                            End If
                        End If
                    Next
                    ExportationText &= CurrentLine
    
                Next
    
                ExportationText = ExportationText.Substring(0, ExportationText.Length - 1)
                WriteText(FileName, ExportationText)
                LastSaveFile = FileName
                Return True
    
            Catch ex As Exception
                Return False
            End Try
        End Function

    Καταλαβαίνω ότι το πρόβλημα υπάρχει γιατί έχω καλέσει Async την πρώτη φόρμα (TodaySelector), το θέμα είναι.. υπάρχει τρόπος να έχω καλεσμένη Async τη φόρμα ΚΑΙ να μπορώ να εμφανίσω το SaveFileDialogue?
    Τι μου προτείνεται να κάνω?


  •  05-08-2012, 20:01 71038 σε απάντηση της 70962

    Απ: Πρόβλημα με SaveFileDialog από Async Form [VB.NET 2010]

    Ναι μπορείς να το κάνεις αλλά θα σου πρότεινα να μην σηκώσεις την φόρμα σε άλλο thread. κάνε Instantiate την φόρμα από το κυρίως thread,
    μην την δείξεις, κάλεσε με async τα functions που αργούν μέσα από αυτήν και μόλις τελειώσουν δείξε την.
    Επίσης όσον αφορά τα "παραδοσιακά" tasks (δεν ξέρω τι γίνεται με async και await) ακόμα και να καλέσεις το ShowDialog method η φόρμα δεν θα είναι modal.

    Το παρακάτω παράδειγμα περνάει από την αρχική φόρμα στην άλλη έναν taskscheduler ο οποίος χρησιμοποιείται από ένα task γιά να δείξει την SaveFileDialog στο αρχικό thread.
    Πιστεύω όμως ότι η πρώτη λύση είναι πιό εύκολη και η πιό σωστή.

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    Option Strict On
    Option Infer Off
    
    Imports System.Threading
    Imports System.Threading.Tasks
    
    Public Class Form1
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Dim sched As TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext
    
            Me.Text = "Είμαι σε: " & Thread.CurrentThread.GetApartmentState.ToString()
    
            Dim tsk As New Task(
                Sub()
                    Dim frm As New Form2(sched)
                    frm.ShowDialog()
                End Sub)
    
            tsk.Start()
        End Sub
    End Class
    
    Public Class Form2 : Inherits Form
        Private _STAScheduler As TaskScheduler
    
        Public Sub New(ByVal STAscheduler As TaskScheduler)
            Dim btn As Button = New Button
    
            btn.Text = "Save As"
            btn.Dock = DockStyle.Top
            AddHandler btn.Click, AddressOf btn_Click
    
            Me.Controls.Add(btn)
    
            _STAScheduler = STAscheduler
    
            Me.Text = "Είμαι σε: " & Thread.CurrentThread.GetApartmentState.ToString()
        End Sub
    
        Private Sub btn_Click(sender As System.Object, e As System.EventArgs)
    
            'Dim frmDlg As New System.Windows.Forms.SaveFileDialog
            'frmDlg.ShowDialog() ' Εδώ Βγάζει το μύνημα
    
            Task.Factory.StartNew(
                Sub()
                    Dim frmDlg As New SaveFileDialog
    
                    frmDlg.Title = "Είμαι σε: " & Thread.CurrentThread.GetApartmentState.ToString()
    
                    frmDlg.ShowDialog()
                End Sub,
                Task.Factory.CancellationToken,
                TaskCreationOptions.None,
                _STAScheduler)
        End Sub
    End Class
  •  05-08-2012, 22:39 71039 σε απάντηση της 71038

    Απ: Πρόβλημα με SaveFileDialog από Async Form [VB.NET 2010]

    wow, πάλι είμαι έξω από τα νερά μου με αυτά τα " :Inherits" "addHandler" "addressOf" και τα λοιπά, αλλά θα τα καταφέρω.


    btw, έχεις απόλυτο δίκιο σε αυτό που λες πάνω, και η αλήθεια είναι ότι δοκίμασα να κάνω ακριβώς αυτό (δλδ να μην καλώ τη φόρμα ολόκληρη ασύγχρονα, αλλά τα functions μόνο),

    ωστόσο μου δημιουργούνται προβλήματα και το άφησα προς το παρόν.


    Θα δοκιμάσω τον κώδικά σου και απαντήσω στο thread.

    btw έχω ακόμα να δοκιμάσω και το άλλο πρόβλημα που μου έλυσες, στο "Εκτύπωση DataGridView πάνω απο 1 σελίδες?". Έτυχαν πολλά αυτές τις μέρες και δεν πρόλαβα να ασχοληθώ, αλλά θα απαντήσω και σε αυτό το thread μέσα στις επόμενες 2 μέρες.


    Σε ευχαριστώ, και να ξέρεις ότι θα είσαι στα credits και αυτού του προγράμματος. πάντα με οδηγείς πιο πέρα, και μαθαίνω καινούργια πράγματα. Το εκτιμώ :)

    Καλό βράδυ, και τα λέμε :D


  •  06-08-2012, 12:23 71040 σε απάντηση της 71039

    Απ: Πρόβλημα με SaveFileDialog από Async Form [VB.NET 2010]

    Τώρα που το κοιτάω μια σκέψη, γιατί είχα ένα παρόμοιο πρόβλημα με το SaveDialog - σε τη βάση είσαι συνδεμένος; Μήπως έχεις κάποιο .accdb αρχείο;

    George J.


    George J. Capnias: Χειροπρακτικός Υπολογιστών, Ύψιστος Γκουράρχης της Κουμπουτερολογίας
    w: capnias.org, t: @gcapnias, l: gr.linkedin.com/in/gcapnias
    dotNETZone.gr News
  •  06-08-2012, 12:50 71041 σε απάντηση της 71040

    Απ: Πρόβλημα με SaveFileDialog από Async Form [VB.NET 2010]

    πράγματι, .accdb είναι, αλλά δεν νομίζω να υπάρχει θέμα με αυτό, γιατί η βάση δεδομένων δεν είναι data source του DataGridView.

    Για την ακρίβεια το DataGridView δεν έχει καθόλου DataSource.

    Τα δεδομένα μπαίνουν με loops διότι θέλω συγκεκριμένα πράγματα μέσα και ανάλογα με το τι θα διαλέξει ο χρήστης.


  •  06-08-2012, 13:38 71043 σε απάντηση της 71041

    Απ: Πρόβλημα με SaveFileDialog από Async Form [VB.NET 2010]

    Δεν το έχω πρόχειρο αυτή τη στιγμή, αλλά πιθανώς το θέμα σου είναι με τον OleDb provider του Office 12 - κάνε μια δοκιμή να αλλάξεις την βάση σε .mdb για να αλλάξεις provider με στον 32bit της παλιάς Access.

    Κάπου είχα διαβάσει ότι ο provider της έκδοσης 12 είχε θέμα με το threading γενικά και κατέβαζε εφαρμογές. Αυτό θα λυνόταν σε μια νεότερη έκδοση...

    George J.


    George J. Capnias: Χειροπρακτικός Υπολογιστών, Ύψιστος Γκουράρχης της Κουμπουτερολογίας
    w: capnias.org, t: @gcapnias, l: gr.linkedin.com/in/gcapnias
    dotNETZone.gr News
  •  06-08-2012, 14:39 71044 σε απάντηση της 71043

    Απ: Πρόβλημα με SaveFileDialog από Async Form [VB.NET 2010]

    Το δοκίμασα αλλά μου βγάζει το ίδιο πρόβλημα δυστυχώς.

    Δεν πειράζει, θα δοκιμάσω και αυτό που πρότεινε ο Libra Storm,

    αλλά προηγείται το θέμα με την εκτύπωση πολλαπλών σελίδων (το οποίο είναι σε άλλο thread και στο οποίο επίσης έχω απάντηση, την οποία θα αρχίσω σε λίγο).


    Πραγματικά δεν ξέρω τι θα έκανα χωρίς τη βοήθειά σας :)


Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems