Visual C#을 사용하여 Microsoft 메시지 큐에 쓰고 읽습니다.

이 문서에서는 Visual C#에서 MSMQ(Microsoft Message Queuing)에 쓰고 읽는 방법을 설명합니다.

원래 제품 버전: Microsoft 메시지 큐
원본 KB 번호: 815811

이 작업에서

요약

이 문서에서 설명하는 내용은 다음과 같습니다.

  • Windows 애플리케이션에서 메시지를 만들고 MSMQ로 보내는 방법입니다.
  • 프라이빗 큐에서 읽고 표시할 메시지 콘텐츠를 역직렬화하는 방법입니다.

요구 사항

다음 항목에서는 필요한 권장 하드웨어, 소프트웨어, 네트워크 인프라, 기술 및 지식 및 서비스 팩에 대해 설명합니다.

  • MSMQ가 설치된 다음 운영 체제 중 하나(4개의 운영 체제에 옵션으로 포함됨): Windows 2000 Professional(또는 서버) 또는 Windows XP Professional(또는 서버).

또한 이 문서에서는 다음에 대해 잘 알고 있다고 가정합니다.

  • MSMQ
  • 명령 프롬프트에서 도구 사용

맨 위로 돌아가기

MSMQ에 쓰기 및 읽기

System.Messaging.NET Framework 네임스페이스에는 MSMQ에서 읽고 써야 하는 클래스가 있습니다. 온라인 청구서 결제 시스템을 모방하는 작은 Windows 애플리케이션을 만들려면 다음 단계를 수행합니다.

  1. Visual Studio .NET 또는 Visual Studio 2005를 엽니다.

  2. Visual C#에서 새 Windows 애플리케이션을 만든 다음 , 이름을 MSMQ로 지정합니다.

  3. 표시되지 않으면 솔루션 탐색기 표시하려면 Ctrl+Alt+L을 누릅니다. 솔루션 탐색기참조를 마우스 오른쪽 단추로 클릭한 다음 참조 추가를 클릭합니다.

  4. .NET 탭의 .dll 파일 목록에서 System.Messaging.dll 파일을 선택합니다. 선택을 클릭한 다음 확인을 클릭합니다.

    참고

    Visual Studio 2005에서 DLL 목록에서 System.Messaging.dll 파일을 클릭한 다음 확인을 클릭합니다.

  5. Form1.cs 디자인 보기에서 열립니다. 열려 있지 않으면 솔루션 탐색기 Form1.cs 두 번 클릭합니다.

  6. Ctrl+Alt+X를 눌러 도구 상자를 엽니다. 도구 상자에서 Windows Forms 탭을 클릭합니다.

  7. 도구 상자에서 다음을 Form1의 가운데로 끌어옵니다.

    • 레이블과 텍스트 상자(각 레이블의 오른쪽에 위치)의 각각에 4개의 행이 있습니다.
    • 레이블 및 텍스트 상자 아래에서 두 개의 단추 컨트롤을 Form1로 끕니다.
  8. 컨트롤을 마우스 오른쪽 단추로 클릭하고 속성을 클릭한 다음 레이블의 Text 속성을 순서대로 다음으로 설정합니다.

    • 결제:
    • 사용자 이름:
    • 금액:
    • 기한:
  9. 속성 대화 상자에서 button1의 Text 속성을 결제 보내기로 설정하고 button2의 Text 속성을 결제 처리로 설정합니다.

  10. 이 애플리케이션은 컴퓨터 관리 콘솔에서 먼저 만들어야 하는 프라이빗 큐에서 작동합니다. 이렇게 하려면 다음과 같이 하십시오.

    1. 바탕 화면에서 내 컴퓨터를 마우스 오른쪽 단추로 클릭한 다음 관리를 클릭합니다.
    2. 서비스 및 애플리케이션 노드를 확장하여 MSMQ를 찾습니다.

    참고

    MSMQ를 찾을 수 없는 경우 설치되지 않습니다.

  11. 메시지 큐를 확장하고프라이빗 큐를 마우스 오른쪽 단추로 클릭하고 새로 만들기를 가리킨 다음 프라이빗 큐를 클릭합니다.

  12. 큐 이름 상자에 billpay를 입력한 다음 확인을 클릭합니다.

    참고

    트랜잭션 검사 상자를 선택하지 마세요. 나중에 다시 돌아와 메시지를 볼 수 있으므로 컴퓨터 관리 콘솔을 열어 둡니다.

  13. Form1의 코드 맨 위에 클래스 선언 앞에 두 개의 USING 문을 추가하여 네임스페이스와 네임스페이스에 상주 System.Messaging 하는 추가 클래스를 System.Text 포함합니다. System.Text(네임스페이스는 문자열을 연결할 때 사용하는 것이 가장 좋은 새 .NET Framework 클래스인 클래스를 사용하기 StringBuilder 위한 것입니다.)

    using System.Messaging;
    using System.Text;
    
  14. 결제를 정의하는 데이터를 저장할 변수가 포함된 구조를 만듭니다. 구조를 만들려면 Main 프로시저 다음에 다음 코드를 추가합니다.

    public struct Payment
    {
        public string Payor,Payee;
        public int Amount;
        public string DueDate;
    }
    
  15. 다음 단계 Click 의 코드를 의 button1이벤트에 추가합니다.

    1. 다음과 같이 구조체의 속성을 양식 요소의 값으로 설정합니다.

      Payment myPayment;
      myPayment.Payor = textBox1.Text;
      myPayment.Payee = textBox2.Text;
      myPayment.Amount = Convert.ToInt32(textBox3.Text);
      myPayment.DueDate = textBox4.Text;
      
    2. 클래스의 Message instance 만든 다음 속성을 구조체 payment 로 설정합니다Body.

      System.Messaging.Message msg = new System.Messaging.Message();
      msg.Body=myPayment;
      
    3. MSMQ에 메시지를 보내려면 클래스의 MessageQueue instance 만들고 개체에 전달하는 메서드를 Message 호출 Send 합니다. 클래스는 MessageQueue MSMQ와의 상호 작용을 관리하는 래퍼입니다.

      참고

      컴퓨터 관리 콘솔에서 만든 프라이빗 큐의 경로를 설정하기 위한 구문입니다. 프라이빗 큐는 형식 machinename\Private$\queuename을 사용합니다. 로컬 호스트 컴퓨터는 점 또는 마침표( 표시됨)로 참조됩니다.

      MessageQueue msgQ =new MessageQueue(".\\Private$\\billpay");
      msgQ.Send(msg);
      

      이제 MSMQ에 메시지를 보내는 코드가 있습니다. .NET Framework 개체를 사용하여 XMLMessageFormatter 메시지를 자동으로 직렬화합니다. 이 개체는 메시지를 보낼 때 암시적으로 만들어집니다.

  16. button2의 이벤트에 다음 단계 Click 의 코드를 추가합니다. button2_Click 이벤트 처리기는 이벤트 처리기에서 button1 전송되는 결제 메시지를 수신하고 처리합니다.

    1. 코드의 첫 번째 줄은 첫 번째 이벤트 처리기에 있는 코드 줄과 동일합니다.

      MessageQueue msgQ = new MessageQueue(".\\Private$\\billpay");
      
    2. 클래스에 전달할 형식의 배열을 만듭니다 XMLMessageFormatter .

      참고

      메시지를 받을 때 이 클래스를 명시적으로 만들어야 합니다. 클래스의 XMLMessageFormatter 생성자는 형식 이름의 문자열 배열 또는 보다 바람직하게는 형식 배열을 Type 사용합니다.

      Payment myPayment=new Payment();
      Object o=new Object();
      System.Type[] arrTypes=new System.Type [2];
      arrTypes[0] = myPayment.GetType();
      arrTypes[1] = o.GetType();
      msgQ.Formatter = new XmlMessageFormatter(arrTypes);
      myPayment=((Payment)msgQ.Receive().Body);
      

      이러한 형식은 XMLMessageFormatter 메시지를 역직렬화하는 방법을 알려줍니다.

    3. 메서드를 호출하여 메시지를 받습니다 Receive . 속성에 Body 액세스하여 메시지 내용을 읽습니다. 속성은 Body 개체를 반환하므로 사용 가능한 형식으로 콘텐츠를 검색하려면 개체를 결제 유형으로 캐스팅해야 합니다.

      StringBuilder sb = new StringBuilder();
      sb.Append("Payment paid to: " + myPayment.Payor);
      sb.Append("\n");
      sb.Append("Paid by: " + myPayment.Payee);
      sb.Append("\n");
      sb.Append("Amount: $" + myPayment.Amount.ToString());
      sb.Append("\n");
      sb.Append("Due Date: " + Convert.ToDateTime(myPayment.DueDate));
      
    4. 결과를 표시하는 메시지 상자를 만듭니다.

      MessageBox.Show(sb.ToString(), "Message Received!");
      

맨 위로 돌아가기

전체 코드 목록(Form1.cs)

using System.Messaging;
using System.Text;
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace WindowsApplication1
{
/// <summary>
/// Summary description for Form1.
/// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.TextBox textBox2;
        private System.Windows.Forms.TextBox textBox3;
        private System.Windows.Forms.TextBox textBox4;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;
        public Form1()
        {
        // Required for Windows Form Designer support
            InitializeComponent();
        // TODO: Add any constructor code after InitializeComponent call
        }
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }
        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.label4 = new System.Windows.Forms.Label();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.textBox2 = new System.Windows.Forms.TextBox();
            this.textBox3 = new System.Windows.Forms.TextBox();
            this.textBox4 = new System.Windows.Forms.TextBox();
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // label1
            this.label1.Location = new System.Drawing.Point(8, 24);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(104, 32);
            this.label1.TabIndex = 0;
            this.label1.Text = "Pay To:";
            // label2
            this.label2.Location = new System.Drawing.Point(8, 80);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(104, 32);
            this.label2.TabIndex = 1;
            this.label2.Text = "Your Name:";
            // label3
            this.label3.Location = new System.Drawing.Point(8, 136);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(112, 32);
            this.label3.TabIndex = 2;
            this.label3.Text = "Amount:";
            // label4
            this.label4.Location = new System.Drawing.Point(8, 184);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(104, 40);
            this.label4.TabIndex = 3;
            this.label4.Text = "Due To:";
            // textBox1
            this.textBox1.Location = new System.Drawing.Point(152, 24);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(128, 20);
            this.textBox1.TabIndex = 4;
            this.textBox1.Text = "textBox1";
            // textBox2
            this.textBox2.Location = new System.Drawing.Point(160, 80);
            this.textBox2.Name = "textBox2";
            this.textBox2.TabIndex = 5;
            this.textBox2.Text = "textBox2";
            // textBox3
            this.textBox3.Location = new System.Drawing.Point(160, 128);
            this.textBox3.Name = "textBox3";
            this.textBox3.Size = new System.Drawing.Size(112, 20);
            this.textBox3.TabIndex = 6;
            this.textBox3.Text = "textBox3";
            // textBox4
            this.textBox4.Location = new System.Drawing.Point(160, 184);
            this.textBox4.Name = "textBox4";
            this.textBox4.Size = new System.Drawing.Size(120, 20);
            this.textBox4.TabIndex = 7;
            this.textBox4.Text = "textBox4";
            // button1
            this.button1.Location = new System.Drawing.Point(8, 232);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(104, 40);
            this.button1.TabIndex = 8;
            this.button1.Text = "Send Payment";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // button2
            this.button2.Location = new System.Drawing.Point(160, 232);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(120, 40);
            this.button2.TabIndex = 9;
            this.button2.Text = "Process Payment";
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // Form1
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.textBox4);
            this.Controls.Add(this.textBox3);
            this.Controls.Add(this.textBox2);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
        }
        #endregion
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }
        private void button1_Click(object sender, System.EventArgs e)
        {
            Payment myPayment;
            myPayment.Payor = textBox1.Text;
            myPayment.Payee = textBox2.Text;
            myPayment.Amount = Convert.ToInt32(textBox3.Text);
            myPayment.DueDate = textBox4.Text;
            System.Messaging.Message msg = new System.Messaging.Message();
            msg.Body=myPayment;
            MessageQueue msgQ =new MessageQueue(".\\Private$\\billpay");
            msgQ.Send(msg);
        }
        private void button2_Click(object sender, System.EventArgs e)
        {
            MessageQueue msgQ = new MessageQueue(".\\Private$\\billpay");
            Payment myPayment=new Payment();
            Object o=new Object();
            System.Type[] arrTypes=new System.Type [2];
            arrTypes[0] = myPayment.GetType();
            arrTypes[1] = o.GetType();
            msgQ.Formatter = new XmlMessageFormatter(arrTypes);
            myPayment=((Payment)msgQ.Receive().Body);
            StringBuilder sb = new StringBuilder();
            sb.Append("Payment paid to: " + myPayment.Payor);
            sb.Append("\n");
            sb.Append("Paid by: " + myPayment.Payee);
            sb.Append("\n");
            sb.Append("Amount: $" + myPayment.Amount.ToString());
            sb.Append("\n");
            sb.Append("Due Date: " + Convert.ToDateTime(myPayment.DueDate));
            MessageBox.Show(sb.ToString(), "Message Received!");
        }
        public struct Payment
        {
            public string Payor,Payee;
            public int Amount;
            public string DueDate;
        }
    }
}

참고

Visual Studio 2005에서 코드를 변경해야 합니다. Windows Forms 프로젝트를 만들 때 Visual C#은 기본적으로 프로젝트에 하나의 양식을 추가합니다. 이 양식의 이름은 Form1입니다. 폼을 나타내는 두 파일의 이름은 Form1.csForm1.designer.cs. Form1.cs 코드를 작성합니다. Designer.cs 파일은 Windows Forms Designer 컨트롤을 추가하여 수행한 모든 작업을 구현하는 코드를 작성하는 위치입니다. Visual C# 2005의 Windows Forms Designer 대한 자세한 내용은 프로젝트 만들기(Visual C#)를 참조하세요.

맨 위로 돌아가기

코드 확인

  1. 디버그 메뉴에서 시작을 클릭합니다.

  2. 각 텍스트 상자에 값을 입력한 다음 결제 보내기를 클릭합니다.

  3. 컴퓨터 관리 콘솔로 돌아갑니다. 청구서 아래의 프라이빗 큐에서 큐 메시지 폴더를 클릭한 다음 MSMQ가 메시지를 받았는지 확인합니다(봉투 아이콘으로 표시됨).

  4. 메시지를 마우스 오른쪽 단추로 클릭하고 속성을 클릭한 다음 본문 탭을 클릭합니다. 결제 메시지가 표시됩니다.

    참고

    결제 메시지의 내용은 XML로 직렬화됩니다.

  5. 청구서 결제 Windows 애플리케이션으로 돌아가 서 결제 처리 단추를 클릭합니다. 메시지 수신을 확인하고 메시지를 표시하는 메시지 상자가 표시됩니다.

맨 위로 돌아가기

문제 해결

  • 프라이빗 큐의 부족은 일반적으로 Windows 2000 Professional 및 Windows XP Professional에서만 문제입니다. Windows 2000 Server 및 Windows XP Server는 공용 큐 사용을 허용합니다.

  • 에 올바른 인수를 전달하는 것은 까다로 XMLMessageFormatter() 울 수 있습니다. 이 예제에서는 생성자에 전달되는 형식 배열에 개체 또는 결제 유형이 포함되지 않은 경우 예외가 throw됩니다.

맨 위로 돌아가기