2011-08-29 2 views
0

데이터베이스 레코드를 업데이트하는 동안 다음 응용 프로그램 코드가 중지됩니다. 출력 화면에 0 만 표시하고 프로그램은 영원히 멈 춥니 다. 그러나 테이블에 50,000 개가 넘는 레코드가 있습니다. 는 (이 프로그램은 유니 코드로 ISCII 코드를 변환하고 데이터베이스에 다시 기록합니다.)데이터베이스 레코드를 업데이트하는 동안 내 응용 프로그램이 멈추는 이유는 무엇입니까?

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Collections; 
using System.Data.SqlClient; 
using System.Data.Sql; 

namespace demoupdateform 
{ 
public partial class Form1 : Form 
{ 
    System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\test1.txt"); 

    String[,] harltabcol = new String[,] 
     { 
      {"Col_name","Table_name"} 

     }; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     SqlConnection cn = new SqlConnection("Password=admin;Persist Security Info=True;User ID=sa;Initial Catalog=dbname;Data Source=DEEPAK-87E8B4"); 
     SqlConnection cn1 = new SqlConnection("Password=admin;Persist Security Info=True;User ID=sa;Initial Catalog=dbname;Data Source=DEEPAK-87E8B4"); 



     string temp; 
     string temp1; 
     try 
     { 

      for (int i = 0; i < harltabcol.GetLength(0); i++) 
      { 

        cn.Open(); 


       SqlCommand cmdSel = new SqlCommand("select [" + harltabcol[i, 0] + "] from [" + harltabcol[i, 1] + "]",cn); 
       //cn.Open(); 
       SqlDataReader rdr = cmdSel.ExecuteReader(); 
       progressBar1.Value = 0; 
       int j = 0; 
       while (rdr.Read()) 
       { 

        temp = (rdr[harltabcol[i, 0]].ToString()).ToString(); 

        temp1 = (Iscii2Unicode(temp)).ToString(); 
        SqlCommand cmdUpd = new SqlCommand("UPDATE [" + harltabcol[i,1] + "] SET [" + harltabcol[i,0] + "] =N'"+temp1+"' WHERE " + harltabcol[i,0] + "='" + temp + "'",cn1); 
        temp = rdr[harltabcol[i, 0]].ToString(); 
        cn1.Open(); 
        cmdUpd.CommandTimeout = 0; 
        Console.WriteLine(j++); 
        file.WriteLine(temp+" --> "+temp1); 
        progressBar1.Value = progressBar1.Value + 1; 

        if (progressBar1.Value == 99) 
         progressBar1.Value = 0; 

        cmdUpd.ExecuteNonQuery(); 
        temp = null; 
        temp1 = null; 
        cn1.Close(); 
       } 
       progressBar1.Value = 100; 
       cn.Close(); 
      } 


     } 
     catch (Exception ex) 
     { 

      MessageBox.Show("Error Occured " + ex.ToString()); 
     } 


    } 
    public string Iscii2Unicode(string IsciiStr) 
    { 
     Encoding EncFrom = Encoding.GetEncoding(1252); 
     Encoding EncTo = Encoding.GetEncoding(57002); 
     Byte[] b = EncFrom.GetBytes(IsciiStr); 

     return EncTo.GetString(b); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 

    } 
} 
} 

답변

4

정상을. 메시지 루프를 실행할 기회를주지 마십시오. BackgroundWorker을 사용하여 DB 쿼리를 처리하고 ProgressChanged으로 전화하여 GUI를 업데이트하십시오.

+0

[WinForms Threading] (http://www.yoda.arachsys.com/csharp/threads/winforms.shtml)의 좋은 자료, 특히 UI 스레드에 관한 부분. 그게 교수형에 처한 이유와 왜 서지의 대답이 그것을 고쳐 주는지 이해하는 데 도움이 될 것입니다. –

1

코드에서 while 루프 내부의 데이터베이스에 충돌하여 프로그램이 중단되었습니다. 따라서 큰 update 쿼리를 생성하고 Command.Execute을 한 번 호출 할 수 있습니다. 이것은 최상의 솔루션은 아니지만 각 반복에 대한 데이터베이스 연결을 열고 닫는 시간을 절약 할 수 있습니다.

StringBuilder updateQuery = new StringBuilder(""); 
while (rdr.Read()) 
{ 
    temp = (rdr[harltabcol[i, 0]].ToString()).ToString(); 
    temp1 = (Iscii2Unicode(temp)).ToString(); 
    updateQuery.Append("UPDATE [" + harltabcol[i,1] + "] SET [" + harltabcol[i,0] + "] =N'"+temp1+"' WHERE " + harltabcol[i,0] + "='" + temp + "';"); 
} 
SqlCommand cmdUpd = new SqlCommand(updateQuery.ToString(),cn1); 
cn1.Open(); 
cmdUpd.CommandTimeout = 0; 
cmdUpd.ExecuteNonQuery(); 
temp = null; 
temp1 = null; 
cn1.Close(); 
cn.Close(); 
+0

Bu 연결 cn 및 cn1은 while 루프를 시작하기 전에 열려야하며 읽기 및 업데이트는 루프 cn 및 cn1이 닫혀 야 한 후에 루프에서 실행되어야합니다 – icaptan

관련 문제