【解決方法】C# で backgroundworker を使用して複数のデータをデータベースに挿入するにはどうすればよいですか?

プログラミングQA


こんにちは、Backgroundworker を使用して MySQL データベースにデータを挿入しようとしていますが、データは実際には OpenFileDialog でユーザーが選択した複数のファイルであり、データベースに送信する前にバイト配列に変換しました。 UI (通常、ユーザーが 3 つ以上のファイルを選択した場合に発生) が応答しないのを防ぐ

私の主な問題は、ユーザーが複数のファイルを選択した場合、データベースに1つのファイルしか挿入されないということです。これは、同時に複数の操作に同じバックグラウンドワーカーを使用しようとしているためです。

これが私のコードです(これによりFileDialogが開き、ユーザーが画像を選択できるようになります):

String getName;
  String retrieved;
  String varDate;
  String nameTable;
  Object keyVal;

  int itemCurr;
  String panName;
  Bitmap picImage;

  int curFilesCount;

  private void _mainFileGenerator(int AccountType_, String _AccountTypeStr_) {
      OpenFileDialog open = new OpenFileDialog();
      open.Filter = "All Files|*.*|Images Files|*.jpg;*.jpeg;*.png;.bmp|";
      open.Multiselect = true;
      varDate = DateTime.Now.ToString("dd/MM/yyyy");

      int curFilesCount = flowLayoutPanel1.Controls.Count;
      if (open.ShowDialog() == DialogResult.OK) {
          foreach (var selectedItems in open.FileNames) {
              _filValues.Add(Path.GetFileName(selectedItems));

                  get_ex = open.FileName;
                  getName = Path.GetFileName(selectedItems);
                  retrieved = Path.GetExtension(selectedItems);

                  if (retrieved == ".png" || retrieved == ".jpeg" || retrieved == ".jpg" || retrieved == ".ico" || retrieved == ".bmp" || retrieved == ".svg") {
                      itemCurr++;
                      nameTable = "file_info";
                      var getImg = new Bitmap(selectedItems);

                      var imgWidth = getImg.Width;
                      var imgHeight = getImg.Height;
                      if (retrieved != ".ico") {
                          using (MemoryStream ms = new MemoryStream()) {
                              getImg.Save(ms,System.Drawing.Imaging.ImageFormat.Png);
                              var setupImg = ms.ToArray();
                              keyVal = setupImg;
                              panName = "PanImg";
                              picImage = getImg;
                          }
                      }
                      else {
                          Image retrieveIcon = Image.FromFile(selectedItems);
                          byte[] dataIco;
                          using (MemoryStream msIco = new MemoryStream()) {
                              retrieveIcon.Save(msIco, System.Drawing.Imaging.ImageFormat.Png);
                              dataIco = msIco.ToArray();
                          }
                      }
                  }
              }
          }

          if (backgroundWorker1.IsBusy) {
              backgroundWorker1.CancelAsync();
          }
          else {
              if (guna2ProgressBar1.Value == guna2ProgressBar1.Maximum) {
                  guna2ProgressBar1.Value = guna2ProgressBar1.Minimum;
              }
              backgroundWorker1.RunWorkerAsync(guna2ProgressBar1.Value);
          }
      }

データの挿入 (DoWork):

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {

    int percentFinished = (int)e.Argument;
    while(!backgroundWorker1.CancellationPending && percentFinished < 100) {
        percentFinished++;
        backgroundWorker1.ReportProgress(percentFinished);
        //System.Threading.Thread.Sleep(50);
    }
    e.Result = percentFinished;

    String insertTxtQuery = "INSERT INTO " + nameTable + "(CUST_FILE_NAME,UPLOAD_DATE,CUST_FILE) VALUES (@CUST_FILE_PATH,@UPLOAD_DATE,@CUST_FILE)";
    command = new MySqlCommand(insertTxtQuery, con);

    command.Parameters.Add("@CUST_FILE_NAME", MySqlDbType.Text);
    command.Parameters.Add("@UPLOAD_DATE", MySqlDbType.VarChar, 255);

    command.Parameters["@CUST_FILE_NAME"].Value = getName;
    command.Parameters["@UPLOAD_DATE"].Value = varDate;

    command.Parameters.Add("@CUST_FILE", MySqlDbType.LongBlob);
    command.Parameters["@CUST_FILE"].Value = keyVal;
    command.ExecuteNonQuery();
}

進行状況バーの値を更新します (ProgressChanged):

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) {
           guna2ProgressBar1.Value = e.ProgressPercentage;
       }

Backgroundworker が完了し、Picturebox に画像が表示されます (RunWorkerCompleted):

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
          guna2ProgressBar1.Value = 0;
          int top = 275;
          int h_p = 100;
          var panelTxt = new Guna2Panel() {
              Name = panName + itemCurr,
              Width = 240,
              Height = 262,
              BorderRadius = 8,
              FillColor = ColorTranslator.FromHtml("#121212"),
              BackColor = Color.Transparent,
              Location = new Point(600, top)
          };

          top += h_p;
          flowLayoutPanel1.Controls.Add(panelTxt);
          var mainPanelTxt = ((Guna2Panel)flowLayoutPanel1.Controls[panName + itemCurr]);

          var textboxPic = new Guna2PictureBox();
          mainPanelTxt.Controls.Add(textboxPic);
          textboxPic.Name = "TxtBox" + itemCurr;
          textboxPic.Width = 240;
          textboxPic.Height = 164;
          textboxPic.BorderRadius = 8;
          textboxPic.SizeMode = PictureBoxSizeMode.CenterImage;
          textboxPic.Enabled = true;
          textboxPic.Visible = true;
          textboxPic.Image = picImage;

          Label titleLab = new Label();
          mainPanelTxt.Controls.Add(titleLab);
          titleLab.Name = "LabVidUp" + itemCurr;
          titleLab.Font = new Font("Segoe UI Semibold", 12, FontStyle.Bold);
          titleLab.ForeColor = Color.Gainsboro;
          titleLab.Visible = true;
          titleLab.Enabled = true;
          titleLab.Location = new Point(12, 182);
          titleLab.Width = 220;
          titleLab.Height = 30;
          titleLab.Text = getName;


          Label dateLabTxt = new Label();
          mainPanelTxt.Controls.Add(dateLabTxt);
          dateLabTxt.Name = "LabTxtUp" + itemCurr;
          dateLabTxt.Font = new Font("Segoe UI Semibold", 12, FontStyle.Bold);
          dateLabTxt.ForeColor = Color.DarkGray;
          dateLabTxt.Visible = true;
          dateLabTxt.Enabled = true;
          dateLabTxt.Location = new Point(12, 208);
          dateLabTxt.Width = 1000;
          dateLabTxt.Text = varDate;
      }

私が試したこと:

foreach ループで backgroundworker のメソッドを読みましたが、現在の問題に関連する/修正されたものはありません。

解決策 1

最も簡単な解決策は、毎回新しいバックグラウンド ワーカーを作成し、SQL に送信する必要があるデータを渡すことです。 自分? 文字列コレクションを渡して、それをバイトに変換してから DB に転送します。

各ファイルを個別に送信する場合は、それを行い、BackgroundWorker.ReportProgress メソッドの UserState パラメーターを介して画像を UI スレッドに戻します。 その後、UI は画像ボックスを更新でき、ワーカーはデータの転送を続行します。

コメント

タイトルとURLをコピーしました