Microsoft MVP성태의 닷넷 이야기
[C# 6.0]multi threading과 ui control [링크 복사], [링크+제목 복사],
조회: 17678
글쓴 사람
힘찬도약 (kssjjw71 at hanmail.net)
홈페이지
첨부 파일
 


 안녕하세요.
 C# 6.0 프로그래밍 책 잘 보고 있습니다.

 제가 지금 개발하고 있는 프로그램은 여러개의 서버에 비동기적으로 접속해서 Packet을 주고 받는 Client프로그램입니다. C#6.0 프로그래밍 10.2.4장 비동기 호출의 병렬처리(675page) 파트 등을 봤습니다만, 본 문제 해결 방법을 잘 못찾겠어서 이렇게 질문드립니다.

Main class에서 serverSockets 객체10개를 생성하고 각각 스레드로 돌아가면서 서버와 데이터를 주고 받는데,
10개의 각각의 스레드에서 주고 받는 데이터를 Main class의 listbox에 출력, 로깅이 가능한지요?
제가 했을 때는, 충돌이 나거나 데이터가 출력이 안되거나 하더라구요.
혹시 해결방법을 알려주시면 감사하겠습니다.








[최초 등록일: ]
[최종 수정일: 10/18/2015]


비밀번호

댓글 작성자
 



2015-10-18 05시35분
일단, UI 요소는 그것을 만든 스레드에서 접근해야 한다는 것만 지켜주시면 됩니다. listbox에 출력이 안된다고 했는데요. 그런 경우 다음과 같이 해보세요.

listbox.Invoke(
    (Action)(() =>
    {
      lstEvent.Items.Add(DateTime.Now + ": " + text);
    }));
정성태
2015-10-18 06시07분
다음의 글을 참고하세요.

[스크랩] Invoke , BeginInvoke, MethodInvoker
; http://www.moros.kr/134
정성태
2015-10-18 07시09분
답변 감사드립니다. 사이트를 보았는데요, 제가 처한 상황에 적용이 잘 안되서요..
  제가 초보이고, 이 부분 해결이 너무 절실한 상황에서 너무 어려워서 그러는데요,
  조금만 더 봐주시고 방법을 좀 제시해주면 안될까요?
  
  코드를 붙여보면, Form1 class가 있고, Form1 class로부터 상속받는 SocketNetworks class가 있는데,
  SocketNetworks class의 TimerCallBack()함수에서 listBox(logOut)에 데이타를 출력하는 방법을 도저히 모르겠어서요.

using System;
 using System.Collections.Generic;
 using System.Threading;
 using System.Windows.Forms;

 namespace jjwThread
 {
     public partial class Form1 : Form
     {
         public Form1()
         {
             InitializeComponent();
         }
         public void Form1_Load(object sender, EventArgs e)
         {
             Thread[] ThreadArr =
             {
                 new Thread(new ThreadStart(Do_Work1)),
                 new Thread(new ThreadStart(Do_Work2)),
             };
             foreach(Thread t in ThreadArr)
             {
                 t.Start();
             }
             logOut.Items.Add(logOut.InvokeRequired);
             logOut.Items.Add(this.Handle);

             List<SocketNetworks> lstServers = new List<SocketNetworks>();

             lstServers.Add(new SocketNetworks("127.0.0.1", 1111));
             lstServers.Add(new SocketNetworks("127.0.0.1", 2222));
             for (int i = 0; i < lstServers.Count; i++ )
             {
                 lstServers[i].SockMainFunc();
             }
             
         }
         private void Do_Work1() // << 잘됨
        {
             //logOut.Items.Add("work1");
             logOut.Items.Add(string.Format("work1: {0}",logOut.InvokeRequired));
             logOut.Items.Add(string.Format("work1_Handle: {0}",this.Handle));
         }
         private void Do_Work2() // << 잘됨
        {
             //logOut.Items.Add("work2");
             logOut.Items.Add(string.Format("work2: {0}", logOut.InvokeRequired));
             logOut.Items.Add(string.Format("work2_Handle: {0}", this.Handle));
         }

     }// end of class Form1

     public class SocketNetworks : Form1
     {
         public string serverIP { get; set; }
         public int serverPort { get; set; }
         private System.Threading.Timer timeGuide;
         public SocketNetworks(string serverIP, int serverPort) {
             this.serverIP = serverIP;
             this.serverPort = serverPort;
         }
         public void SockMainFunc() {
             timeGuide = new System.Threading.Timer(TimerCallBack);
             timeGuide.Change(0, 1000 * 2);
         }

         private void TimerCallBack(object obj)
         {
             logOut.Items.Add(string.Format("TimerCallBack_Handle: {0}", this.Handle)); <<<<<<<<< ?
             // logOut 자체를 인식하지 못해서 컴파일 에러

            logOut.Invoke( <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ?
              (Action)(() => {
                  lstEvent.Items.Add(DateTime.Now + ": " + text);
              }));

             int i=0;
             i++;
             if(i>3000) i=0;
         }
     }
 }

힘찬도약
2015-10-19 12시39분
logOut 자체를 인식하지 못하는 것은 Form1에 정의된 해당 변수가 private으로 선언되어 있어서 그럴 것입니다. 이럴 때는 Form1에 logOut을 노출해주는 protected나 public의 속성을 정의해 주시면 됩니다. 일단 그렇게 하면 컴파일은 되고... 하지만 TimerCallBack 메서드에서 실행시 예외가 발생할 것입니다. 그건 이 질문의 첫번째 답변과 관계 있으니 다시 한번 잘 읽어보시고 그래도 모르시겠으면 한번 더 질문을 주세요.
정성태
2015-10-19 04시21분
[힘찬도약] logOut이 public으로 잡으니 컴파일이 되었습니다. 당연하지만, 실력이 미천해서... 몰랐습니다. ^^

class Form1 안에 다음과 같은 로깅함수를 만들어 놓고,
TimerCallback에서 Log_Out("제발..."); 함수를 부르면 listbox에 안찍히는데요,
찍어야 디버깅이 되는데.. 제발 도와주세요...

public void Log_Out(string strLog)
{

   if(this.InvokeRequired)
   {
      this.Invoke(new MethodInvoker(
           delegate()
          {
            logOut.Items.Add(strLog);
          }
       )
       );
    }
    else
    {
       logOut.Items.Add(strLog);
    }
  }
[guest]
2015-10-19 08시06분
[spowner] 방장님이 답변을 드리기 모호한 지점에 있는 것 같습니다.
Invoke를 떠나서 "Log_Out" 메소드가 호출은 되는지 확인해보세요. 아마 정황상 "log_Out"메소드 자체가 호출 안되는 것 처럼 보이는데 그 이유는 별개의 이유입니다.
[guest]
2015-10-19 09시14분
[힘찬도약] 브레이크포인트 잡고 런(스텝)시키면 들어옵니다. 들어는 오는데, this.InvokeRequired가 false여서(-> ?) 밑에 구문을 탑니다. 그런데 listbox에는 출력이 안됩니다.
[guest]
2015-10-19 10시46분
@힘찬도약 님, InvokeRequired가 false면 스레드 문제는 아닌데요. 재미있군요. ^^ 혹시, 재현가능한 최소한의 소스를 첨부해주시겠어요.
정성태
2015-10-19 12시16분
수정으로 첨부파일이 안올라가서,
답변 글로 첨부파일 올렸습니다.
힘찬도약

[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
5968orion4/30/2025242winform DataSet.xsd의 암호화 된 ConnectionString 사용 질문 [2]
5966GM B4/30/2025259C#과 python 연동 질문 [1]
5962SunN...4/21/2025559Contextmenu margin 조절 [1]파일 다운로드2
5961GM B4/10/2025955winform => wpf 마이그레이션 방법 질문 [4]파일 다운로드1
5960Kim ...4/9/20251209안녕하세요.. 혹 AI & C# 에 대해서도 다루시나요? [1]
5959vict...2/10/20251900비주얼 스투디오 CLR 코드 탑색 질문입니다. [1]
5958Supe...1/18/20252889C#으로 DLL을 만들때 WebVeiw2을 이용하여 Vb6에서 사용할수 있는지 문의드립니다. [2]
5956fc1/11/20252889한국투자증권 KIS Developers OpenAPI의 C# 래퍼 버전 - eFriendOpenAPI NuGet 패키지 [1]
5955tree...11/8/20244514C#12 책 179 페이지 문의 사항 [2]
5954SunN...10/10/20244987textbox에서 글자입력후 textBox1_KeyUp함수에서listBox1_SelectedIndexChanged 강제호출방법 [1]
5953Roya10/4/20244977c# com host dll을 c++에서 사용할 때, sdk 관련 runtime 을 설치 안하고 제공할수 있을까요?? [1]
5952우광현9/5/20246086서버용 소켓 포트 동적포트 적용시 클라이언트가 호출하는 방법? [2]
5951Kun ...8/21/20245700c++에서 복합데이터 Struct를 .NET Framework에서 구현할 수 있는 방법이 있을까요? [2]
5950SunN...8/18/20246269정석대로 한다면 response.Close() 해야되는지요? [4]
5949SunN...8/16/20246366SqlConnection Open()에서 에러가나면 Close()하는 시점 [3]
5948SunN...8/14/20246228WebRequestMethods.Ftp.MakeDirectory 해제 [3]
5947Roya8/7/20247004c# dll을 cpp lib에서 사용을 할려고 하는데요. CoCreateInstance 에서 지정된 파일을 찾을수 없다고 나오는대요. [4]
5946SunN...8/5/20247111TaskDefinition 에서 사용저가로그온상관없이실행 [3]파일 다운로드1
5945SunN...8/3/20246987윈도우 작업스케줄러 [1]
5944roya8/1/20246926C# dll을 C++ 프로젝트에서 사용을 하고 싶은데, 레지스트리 등록 없이 가능한걸까요?? [2]
5943SunN...8/1/20246805윈도우C#에서 리눅스FTP로 업로드 및 리눅스에 폴더생성(WindowsOS에서C#으로) [3]
5942vict...7/24/20246837dll 을 c#에서 쓰고 싶습니다 [1]
5941vict...7/17/20248337DependencyObject와 같은 스레드에서 DependencySource를 만들어야 합니다. 오류 [2]
5940ckm7/16/20248752선생님 안녕하세요 async await 교착 관련 질문입니다 [1]
5939괴물신인7/9/20248444템플릿 대체할수있는방법이 있을까요? [6]
[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...