Announcement

Collapse
No announcement yet.

Datei löschen - Exception ( Datei wird von einem anderen Prozess verwendet )

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Datei löschen - Exception ( Datei wird von einem anderen Prozess verwendet )

    Hallo,

    Habe gerade gesehen, daß gestern auch jemand ein "Datei löschen"-Thema erstellt hat.
    Wie ich Dateien lösche, weiß ich generell.

    Ich habe das Problem, daß ich beim Löschen einer Datei eine Exception bekomme, die besagt, daß die Datei von einem anderen Prozess verwendet wird.
    Es handelt sich um Dateien, die remote auf einem Terminalserver liegen.

    Das Löschen an sich bewerkstellige bzw. versuche ich derzeit auf diesem Wege:
    [highlight=csharp]
    private void _deleteFiles() {


    if ( chkDelete.Checked ) {


    String filePath = @"\\SRVxxx\C$\Users\" + cmbDesktops.Text + @"\Desktop\{filename}";


    foreach ( object i in chkListPDF.CheckedItems ) {


    File.Delete( filePath.Replace("{filename}", i.ToString()) );


    }


    }


    }
    [/highlight]
    Ich gehe also eine CheckedComboBox durch und möchte alle darin markierten Dateien löschen.

    Die Dateien existieren natürlich physikalisch und wurden einen Step vorher wie geplant per Mail an mich versendet.
    Das Löschen wird direkt nach dem Versand der Mail durchgeführt.

    An dem Punkt bekomme ich die Exception
    Code:
    Der Prozess kann nicht auf die Datei "\\SRVxxx\C$\Users\xxx\Desktop\Leitfaden_xxx.pdf" zugreifen, da sie von einem anderen Prozess verwendet wird.
    ...und ich weiß nicht, warum.
    Auf dem TS ist defintiv keine Anmeldung von mir aktiv, noch ist eine dieser Datei geöffnet.

    Mache ich evtl. grundsätzlich was falsch beim Löschen.

    Danke und Gruß
    Arne
    PHP rocks!
    Eine Initiative der PHP Community

  • #2
    Ich habe das Problem, daß ich beim Löschen einer Datei eine Exception bekomme, die besagt, daß die Datei von einem anderen Prozess verwendet wird.
    Es muß kein anderer Prozess sein, oft genug ist man es selbst weil man vorher denn Handle nicht explizit geschlossen hat.
    Möglich wäre auch das du nur glaubst das die Datei versendet wurde aber noch in der OutBox hängt und gerade im ~versenden~ ist.

    ...und ich weiß nicht, warum.
    Auf dem TS mal in der Computerverwaltung/Freigegebene Ordner/Geöffnete Dateien/ nachschauen ob dein File da auftaucht.

    Comment


    • #3
      Teste das mal ohe das versenden per eMail. Wenn das geht ist offenbar der Sendevorgang noch nicht abgeschlossen
      Christian

      Comment


      • #4
        Ihr habt recht, der Versand ist in dem Moment noch gar nicht abgeschlossen. Das hatte ich allerdings angenommen, weil die MessageBox sich schon gemeldet hat:
        [highlight=csharp]
        private void btnSend_Click( object sender, EventArgs e ) {


        DateTime zeit = DateTime.Now;


        MailMessage mail = new MailMessage( "[email protected]", txtTo.Text );
        SmtpClient smtp = new SmtpClient();
        Attachment pdf;


        String filePath = @"\\SRVxxx\C$\Users\" + cmbDesktops.Text + @"\Desktop\{filename}";


        if ( chkListPDF.CheckedIndices.Count > 0 ) {
        smtp.Port = 25001;
        smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
        smtp.Credentials = new System.Net.NetworkCredential( "user", "password" );
        smtp.Host = "SRVyyy";


        mail.Subject = "Deine Remote Desktop PDF-Dateien ( " + zeit.ToString( "dd.MM.yyyy HH:mm:ss" ) + " )";
        mail.Body = "moin :-)";


        MailAddress bcc = new MailAddress( "[email protected]" );
        mail.Bcc.Add( bcc );


        foreach ( object item in chkListPDF.CheckedItems ) {


        pdf = new Attachment( filePath.Replace( "{filename}", item.ToString() ) );
        mail.Attachments.Add( pdf );


        }


        smtp.Send( mail );


        MessageBox.Show( "Gesendet" );
        this._deleteFiles();


        } else {


        MessageBox.Show( "Bitte mindestens eine Datei auswählen." );


        }


        }
        [/highlight]Kann ich den Status von smtp.Send() evtl. in einer while prüfen, quasi solange keine Rückmeldung kommt oder ähnliches?

        Danke
        PHP rocks!
        Eine Initiative der PHP Community

        Comment


        • #5
          Nein, da Send nichts zurückgibt, ist auch nichts zum prüfen da

          https://msdn.microsoft.com/de-de/lib...vs.110%29.aspx
          Christian

          Comment


          • #6
            Ok, danke für den Link.
            Wenn ich das richtig sehe, müsste ich also den Versand in eine von SmtpClient abgeleitete Klasse auslagern, um die OnSendCompleted nutzen zu können?
            PHP rocks!
            Eine Initiative der PHP Community

            Comment


            • #7
              Würde ich machen....
              Christian

              Comment


              • #8
                Ok, danke!
                PHP rocks!
                Eine Initiative der PHP Community

                Comment


                • #9
                  Auf SendCompleted zu prüfen ist sicher richtig aber warum die Methode überschreiben anstatt einfach den SendCompleted Event fangen? OnSendCompleted macht standardmäßig eh nur das werfen dieses Events.

                  Comment


                  • #10
                    Wo Du recht hast, hast Du recht... Danke für den Nachtrag.
                    PHP rocks!
                    Eine Initiative der PHP Community

                    Comment


                    • #11
                      Also ändern tut sich das nicht wirklich. Ich vermute, daß ich da etwas noch nicht ganz korrekt umsetze.

                      Ich starte den Sende-Vorgang nun so:
                      [highlight=csharp]
                      smtp.SendCompleted += new SendCompletedEventHandler( _smtpSendCompletedEventHandler );
                      smtp.SendAsync( mail, "foobar" );[/highlight]

                      Mein EventHandler sieht entsprechend dem Link von Ralf so aus:
                      [highlight=csharp]
                      private void _smtpSendCompletedEventHandler( object sender, AsyncCompletedEventArgs e ) {

                      String _token = e.UserState.ToString();
                      Boolean _hasError = ( e.Error != null );

                      if ( _hasError ) {


                      MessageBox.Show( "Fehler: " + e.Error.ToString() );


                      } else {


                      MessageBox.Show( "Mail wurde versendet" );
                      _mailSent = true;


                      }

                      }
                      [/highlight]

                      Setze ich jetzt anstelle des _mailSent = true bspw. den Aufruf this._deleteFiles(), bekomme ich wieder die Eingangs erwähnte Exception.
                      Gut, deswegen ja auch der Parameter _mailSent, aber an welcher Stelle soll ich den sinnvoll abfragen? Das Versenden läuft asynchron, also wird eine Abfrage per IF nie true ergeben ( ebenfalls getestet ).

                      Ein kleines Verständnisproblem habe ich da also noch, wie man sieht.
                      Ich hoffe, daß ihr mir da nochmal Input geben könnt?

                      Danke
                      Arne
                      PHP rocks!
                      Eine Initiative der PHP Community

                      Comment


                      • #12
                        Nein, das mit dem Parameter ist sinnlos. Das führt die ganze Methode und deren Sinn ad Absurdum.

                        https://msdn.microsoft.com/en-us/lib...vs.110%29.aspx

                        Ev. ist ein Dispose erforderlich

                        Andere Möglichkeit
                        Lagere das senden in einen eigenen Thread aus https://msdn.microsoft.com/en-us/lib...=vs.71%29.aspx und sende dann nicht asynchron. Dann wird bei smtp.send der Thread solange angehalten, bis das senden erledigt ist. Dann müsste ja das löschen der Dateien als letzte Anweisung im Thread funktionieren
                        Christian

                        Comment


                        • #13
                          Von der Erklärung her logisch. Ich habe jetzt mal versucht, das in einen Thread zu setzen.
                          Vermutlich nicht ganz richtig, aber ich lese es nicht sonderlich anders raus in den Tutorials.

                          Ich habe also jetzt den Aufbau und Versand der Mail in eine neue Methode _sendMail() gepackt. In dieser Methode wird, wie zuvor dann auch das smtp.Send( mail ) ausgeführt.

                          Starten tue ich den Thread folgendermassen:
                          [highlight=csharp]
                          Thread SendMail = new Thread( new ThreadStart(_sendMail) );
                          SendMail.Start();[/highlight]
                          Meinem Verständnis nach ist das aber ebenso sinnlos wie zuvor, denn wenn ich das Löschen der Dateien in den Thread mit reinpacke, habe ich das Problem ja nur verlagert.
                          smtp.Send() ist nicht fertig, zu dem Zeitpunkt, an dem ich die Dateien löschen möchte. Ob ich mich dazu in einem Thread befinde oder nicht, dürfte egal sein.

                          Für mich bedeutet das, daß ich also warten muß, bis der Thread beendet ist, was ich aber so nicht gefunden habe, muß ich zugeben.
                          Bin ich jetzt voll verplant oder geht's zumindest in die richtige Richtung?

                          Danke für eure Geduld!
                          Arne
                          PHP rocks!
                          Eine Initiative der PHP Community

                          Comment


                          • #14
                            Es ist ein Unterschied zwischen
                            smtp.Send() -> Beitrag #4
                            und
                            smtp.SendAsync() -> Beitrag #11

                            Ersteres sollte warten bis das senden fertig ist. Deswegen im Thread ersteres verwenden
                            Christian

                            Comment


                            • #15
                              Das habe ich ja auch soweit verstanden, aber der Logik zufolge hätte #4 schon funktionieren müssen, weil dort verwende ich ja smtp.Send()!
                              Heißt, es sollte warten, bis das Senden fertig ist. Tut es aber nicht, das war ja mein Eingangsproblem.
                              Der nächste Schritt, das in einen Thread zu kapseln, kann ich noch nachvollziehen, aber dennoch benötige ich dann ja bspw. ein Event, das mir signalisiert, wann der Thread abgeschlossen ist.

                              Ich fand ja auch die asynchrone Variante sinnvoll, bei der ich dann ja über das Completed-Event eingreifen konnte, was aber auch nichts daran verändert hat, daß das Exception-Handling meint, die Dateien werden von dem Prozess noch verwendet.
                              PHP rocks!
                              Eine Initiative der PHP Community

                              Comment

                              Working...
                              X