'C#'에 해당되는 글 4건

  1. 2008/03/14 C# Thread DataGridView Invoke.
  2. 2007/11/18 찰스 페졸드 - WPF 정리.!
  3. 2007/11/09 SSL 인증서 만료일 가져오기!!!! (4)
  4. 2007/11/06 C#으로 Excel Control (4)

C# Thread DataGridView Invoke.

C# 2008/03/14 11:42 posted by isili

c# 윈도우 프로그래밍에서 DataGridView를 윈도우 위에 올려 놓고.

메인 스레드에서 새로운 쓰레드=t1 생성 후에

t1에서 그리드 뷰를 연신 Clear 했더니......

간헐적으로 에러가 나는게 아니겠습니까..

그래서 Debug 모드로 실행을 시켰더니..

친절하게

방법: 스레드로부터 안전한 방식으로 Windows Forms 컨트롤 호출

이런 도움말을 뽑아 주더라구욤.

에러가 발생한 원인은

.NET Framework에서는 사용자가 스레드로부터 안전하지 않은 방식으로 컨트롤에 액세스할 경우 이를 감지할 수 있습니다. 디버거에서 응용 프로그램을 실행할 때 컨트롤을 만든 스레드가 아닌 스레드에서 해당 컨트롤을 호출하려고 하면 디버거에서 InvalidOperationException을 발생시키고 "컨트롤 이름 컨트롤이 자신이 만들어진 스레드가 아닌 스레드에서 액세스되었습니다."라는 메시지를 표시합니다.

-> 아래와 같은 상황도 첨부되어 있습니다. 그러니까 프레임워크 2.0 이하 버전에서는 이런 예외가 발생하지 수 있다는 말이군요.

이 예외는 일부 환경에서 런타임에 디버깅하는 동안 안정적으로 발생합니다. 이 예외가 발생할 경우 문제를 수정하는 것이 좋습니다. 이 예외는 .NET Framework 2.0 이전 버전에서 작성한 응용 프로그램을 디버깅할 때 발생할 수 있습니다.

이제 저런 문제는 어떻게 처리하는가!?!?

스레드로부터 안전한 방식으로 Windows Forms 컨트롤 호출

스레드로부터 안전한 방식으로 Windows Forms 컨트롤을 호출하려면

1.컨트롤의 InvokeRequired 속성을 쿼리합니다.

2. InvokeRequired가 true를 반환하는 경우에는 컨트롤을 실제로 호출하는 대리자를 사용하여 Invoke를 호출합니다.

3. InvokeRequired가 false를 반환하는 경우에는 컨트롤을 직접 호출합니다.

좀 더 자세한 정보는
http://msdn2.microsoft.com/ko-kr/library/ms171728.aspx 

EX DataGridView Clear ,add 예제 )

 delegate void DelegateThreadClaer();
        private void GridViewClear()
        {
            this.BoardGridView.Rows.Clear();
        }
  delegate void DelegateThreadAdd(string [] row);
        private void GridViewAdd(string[] row)
        {
            this.BoardGridView.Rows.Add(row);
        }

 if (this.BoardGridView.InvokeRequired)
     {
       DelegateThreadClaer del = GridViewClear;
       this.BoardGridView.Invoke(del);
       }
  else
   {
       BoardGridView.Rows.Clear();
    }
  if (this.BoardGridView.InvokeRequired)
    {
       DelegateThreadAdd add = GridViewAdd;
       this.Invoke(add,new object[]{row});
    }
   else
   {
       BoardGridView.Rows.Add(row);
   }

찰스 페졸드 - WPF 정리.!

C# 2007/11/18 23:17 posted by isili

순수하게 공부용입니다.

1. Application 과 Window.

간단한 소스와 함께 시작되었습니다.

26P 에 보시면.
"WPF 프로그램에서는 [STAThread] 속성이 반드시 Main 앞에 나와야 한다." 
라는 부분이 있는데...

그렇지 않으면 InvalidOperationException 예외 상황과 함께 프로그램이 종료 된다고 ...

친절하게도 위의 속성은 단일 쓰레드 아파트먼트로 지정하는 것을 의미 한다고 적혀있습니다.

여기에서 질문! 단일 쓰레드 아파트먼트?
구글에 물어보았습니다.. 역시나 MSDN!?

Using single-threaded apartments (the apartment model process) offers a message-based paradigm for dealing with multiple objects running concurrently.
싱글 쓰레드 아파트먼트를 사용한다는 것은 멀티플 오브젝트를 동시에 다루기 위한 메시지 기반의 패러다임을 제시한다.

  It enables you to write more efficient code by allowing a thread, while it waits for some time-consuming operation to complete, to allow another thread to be executed.
그것은 너가 효율적인 코드를 하나의 쓰레드에서 작성할수 있도록 한다.  하나의 작동이 끝난다면 다른 쓰레드가 실행될 수 있도록 허가한다.

Each thread in a process that is initialized as an apartment model process, and that retrieves and dispatches window messages, is a single-threaded apartment thread.
한 프로세스에서 각 쓰레드는 하나의 아파트 모델 프로세스에 의해 초기화 되고 되찾고, 윈도우 메시지에 의해 처리된다. 싱글쓰레드 아파트 먼트이다. (개판)

Each thread lives within its own apartment
각각의 쓰레드는 자신의 아파트 먼트를 가진다.

Within an apartment, interface pointers can be passed without marshaling, and therefore, all objects in one single-threaded apartment thread communicate directly.
하나의 아파트먼트 안에서 인터페이스 포인터는 마샬링 없이 통과될수 있다 따라서 모든 오브젝트는 하나의 쓰레드 안에서 직접적으로 통신할 수 있다.

A logical grouping of related objects that all execute on the same thread, and therefore must have synchronous execution, could live on the same single-threaded apartment thread.
논리적으로 그루핑된 오브젝트는 하나의 쓰레드에서 실행된다 따라서 동기적으로 실행되어여 하고 같은 싱글쓰레드 아파트먼트에서 존재해야 한다.(역시 개판)

an apartment model object cannot reside on more than one thread.
하나의 아파트 모델 오브젝트는 다른 쓰레드에 존재할 수 없다.

Calls to objects in other processes must be made within the context of the owning process, so distributed COM switches threads for you automatically when you call on a proxy.

http://www.codeproject.com/com/CCOMThread.asp (참고자료)

머 저정도로 설명하고, 사실 책에는

어플리케이션이 다중 쓰레드를 사용하지 않는다는 것을 의미한다고 간단하게 설명하였음.

첫번째 기초프로그램을 제작하기 전에 반드시 해야할 것이 있다면..

27P 3번 PresentationCore , PresentationFramework, System, WindowBase를 반드시 포함.

VS2005를 켜고 C# WPF Template 를 찾아보았으나 존재하지 않음.
이곳 저곳 찾아보다가..

"먼저 개발을 위한 요구사항은 먼저 .NET 3.0 Framework(http://www.microsoft.com/downloads/details.aspx?familyid=10CC340B-F857-4A14-83F5-25634C3BF043&displaylang=ko)를 설치해야 한다. 그리고 2개를 더 설치해줘야 하는데..  Microsoft Windows SDK for .NET Framework 3.0와  Visual Studio 2005 extensions for .NET Framework 3.0 (WCF & WPF)를 순서대로 설치해야 한다. 물론 이 모두에 앞서 OS(Win2000, XP, Vista)와 Visual Studio 2005가 설치되어져 있어야 한다. 참고로 필자의 OS는 .NET 3.0이 이미 설치된 윈도우즈 비스타이다."


위의 준비 사항을 마치면.

직접적으로 WPF 프로그래밍을 시작할 수 있다.

# 이벤트 처리 - 마우스 버튼 클릭 이벤트
[STAThread]
        public static void Main()
        {
            Application app = new Application();
          - 어플리케이션 생성

            Window win = new Window();
            - 윈도우 생성
            win.Title = "Handler An Event";
            win.MouseDown += WindowOnMouseDown;

            app.Run(win);
        }
        static void WindowOnMouseDown(object sender, MouseButtonEventArgs args)
        {
            // 이벤트 핸들러의 첫번째 인자는 이벤트를 발생시키는 객체인데, 여기에서는 Window 객체가 된다.
            // 이벤트 핸들러는 이 객체를 Window 타입의 객체로 형 변환한다.
            Window win = sender as Window;

            string strMessage
            = string.Format("Window Click {0}, {1}", args.ChangedButton, args.GetPosition(win));

            MessageBox.Show(strMessage);
        }


 이 프로그램에서 이벤트 핸들러에 Window 객체가 필요한 이유는 두 가지다. 첫 번째 이유는 MouseButtonEventArgs 클래스에 정의된 GetPosition 메소드의 인자로 Window 객체를 넘거야 하기 때문이다. - GetPosition 메소드는 인자로 넘긴 객체의 좌측 상단을 기준으로하는 마우스의 위치를 반환한다.

이 프로그램의 이벤트 핸들러에는 sender 인자를 Window 타입의 객체로 형 변환하고 있지만, 동일한 Window 객체를 이벤트 핸들러 안에서 구하는 방법도 있다.

Main에서 생성된 Window 객체는 정적 필드로 저장돼, 이벤트 핸들러에서 이를 사용할 수 있다.
또 다른 방법으로 Application 클래스의 특정 프로퍼티를 사용해도 된다. (Applicatioin 객체의 Current 프로퍼티)

Application 클래스에는 유용한 몇 가지 이벤트가 정의되어 있는데 이런 이벤트를 처리할 필요가 있다면 Application을 상속하는 클래스를 정의하는 것이다. (오버라이딩을 이용)

# Application 상속을 통한 오버라이딩 구현
# 이벤트 핸들러 관련
class InheritApp : Application
    {
        [STAThread]
        public static void Main()
        {
            InheritApp app = new InheritApp();
            app.Run();
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            Window win = new Window();
            win.Title = "상속 받은 APP";
            win.Show();
        }

        protected override void OnSessionEnding(SessionEndingCancelEventArgs e)
        {
          // 제대로 호출이 되질 않고 있음.
          // 해당 코드를 Vista에서 재구동해 보겠음
            base.OnSessionEnding(e);
            MessageBoxResult result = MessageBox.Show("Do you want to save your data?", MainWindow.Title,
                MessageBoxButton.YesNoCancel, MessageBoxImage.Question, MessageBoxResult.Yes);

            // 취소를 누르게 되면 Cancel 플래그를 true 설정하게 되어 종료를 막는다.
            e.Cancel = (result == MessageBoxResult.Cancel);
         
        }
    }

# Application 상속을 통한 오버라이딩 구현
# 부모, 자식 윈도우 관련
  class ThrowWindowParty : Application
    {
        [STAThread]
        public static void Main()
        {
            ThrowWindowParty app = new ThrowWindowParty();
            app.Run();
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            //base.OnStartup(e);
            Window winMain = new Window();
            winMain.Title = "Main Window";
            winMain.MouseDown += WindowOnMouseDown;
            winMain.Show();

            for (int I = 0; I < 2; I++)
            {
                Window win = new Window();
                win.Title = "Ex" + (I + 1);
                win.Show();
            }
        }
        void WindowOnMouseDown(object sender, MouseButtonEventArgs args)
        {
            Window win = new Window();
            win.Title = "Modal Dialog Box";
            win.ShowDialog();
        }

    }
// 총 3개의 창이 생성되는데 전부 동등함.
// Application 객체의 MainWindow 프로퍼티를 살펴보면 Show가 호출되는 첫 창이 그 애플리케이션에서 메인 창으로 간주되는 것을 알 수 있다.
// 일반적으로 Run 메소드가 반환될 때 프로그램이 종료되는데 , 마지막 창을 닫을 경우에 Run 메소드가 반환된다. 이와 같은 동작은 Application의 ShutdownMode 프로퍼티를 어떻게 설정하느냐에 따라 다르게 결정.
이 프로퍼티는 ShutdownMode 열거형의 멤버로 설정한다.

기본적으로 ShutdownMode.OnLastWindowClose 멤버가 지정돼있지만 이제 ShutdownMode.OnMainWindowClose로 설정할 경우 Main윈도우가 닫힐 경우 전체 윈도우가 닫힌다.

ShutdownMode에는 OnExplicitShutdown도 포함되어 있는데 Application의 Shutdown 메소드를 명시적으로 호출하는 경우에만 Run이 반환된다.

SSL 인증서 만료일 가져오기!!!!

C# 2007/11/09 20:37 posted by isili

SSL_EXPIRE_DAY!
인증하시는 분들께는 상당히 유용하실 듯.
---------------------------------------------------
유징해야 하는 것들.
using System;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.Collections;
using System.Security.Cryptography.X509Certificates;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
---------------------------------------------------

Main 함수

// 객체 생성 //
// url 과 포트를 입력 받는다.
cExpire myExpire();
//

class CExpire
{
       
        public CExpire()
        {
       // 초기화 할 것들 입력.        
       // 전 딱히 없네요.    
        }
        public void GetInformation(string url, int port)
         {
               try
               {
                    ConnectToSite(url,port);
                }catch(Exception e)
                 {
                     Console.Error.WriteLine(e.Message);
                  }
          }
          public static void ConnectToSite(string servername , int port)
          {
                TcpClient client = new TcpClient(servername, port);
                  // 콜백 부분은 잘 조정하면 될듯..
                  SslStream sslStream = new SslStream(client.GetStream(), false,
                    new RemoteCertificateValidationCallback(ValidateServerCertificate) , null );
 
                 try
                 {  
                             sslStream.AuthenticateAsCliet(servername);
                  }catch(AuthenticationException e)
                  {
                             client.Close();
                              return ;
                   }
             }
             private static bool ValidateServerCertificate ( object sender,
            X509Certificate certificate,
            X509Chain chain,
            SslPolicyErrors sslPolicyErrors
            )
             {
            Console.WriteLine("Subject : {0}\n", certificate.Subject);
            Console.WriteLine("Subject : {0}\n", certificate.Issuer);
            Console.WriteLine("Subject : {0}\n", certificate.GetSerialNumberString());
            Console.WriteLine("Subject : {0}\n", certificate.GetExpirationDateString());
             return true;  
           }
                   
           }
       
}

C#으로 Excel Control

C# 2007/11/06 18:06 posted by isili

 //
 // 엑셀파일 한 줄을 읽어와서 화면에 출력하는 프로그램.
 //

Firststep.

참조추가:
COM -> Microsoft Excel 11.0 Object Library(Office 버전 별로 다름)
을 추가.

Secondstep

// 이런 식으로 using 하면 조금더 쉽게 사용할 수 있음.
using Excel = Microsoft.Office.Interop.Excel;  

// Excel 실행
            Excel.Application objExcel = new Excel.Application();
            Excel.Workbook objExcelWorkbook;
            Excel.Worksheet objExcelWorksheet;
// 엑셀 실행후 -> Workbook에 담는다.
objExcelWorkbook = objExcel.Workbooks.Open(@"c:\\test.xlsx",
           Missing.Value, Missing.Value, Missing.Value,
           Missing.Value, Missing.Value, Missing.Value, Excel.XlSaveAsAccessMode.xlNoChange,
           Missing.Value, Missing.Value, Missing.Value, Missing.Value,
           Missing.Value, Missing.Value, Missing.Value);
           
// 워크 시트 중에 1번째 것을 가져온다.
objExcelWorksheet = (Excel.Worksheet)objExcelWorkbook.Worksheets[1];

// 워크 시트중에서 가져올 부분을 range를 통해 긁어온다.
Excel.Range range = null;
range = objExcelWorksheet.get_Range("A1", "A9");
// 여기서 불만 위에서 처럼 가져올 부분을 반드시 입력을 해야 하는 것인가.
// A에 있고 ""이 아니면 가져올 수 있는 방법은 연구를 해봐야 하겠음.

// 일종의 팁으로 값이 있는 가장 마지막 행로 이동하는 메쏘드.
range = range.get_End(Microsoft.Office.Interop.Excel.XlDirection.xlDown);

Third Step.

모든 작업을 순차적으로 완료 하였을 경우
아래와 같은 Close 부분을 추가하여야 한다.

       objExcel.Workbooks.Close();
       objExcel.Quit();

        range = null;
        objExcelWorksheet = null;
        objExcelWorkbook = null;
        objExcel = null;

아래와 같이 입력하지 않았을 경우 excel.exe 인스턴스가 계속 상주하게 되어 파일이 읽기 전용으로 열린다.

TAG c#, Excel, 엑셀