Microsoft MVP성태의 닷넷 이야기
[C# 6.0]multi threading과 ui control [링크 복사], [링크+제목 복사]
조회: 11543
글쓴 사람
힘찬도약 (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분
수정으로 첨부파일이 안올라가서,
답변 글로 첨부파일 올렸습니다.
힘찬도약

... 31  32  33  34  35  36  37  38  39  [40]  41  42  43  44  45  ...
NoWriterDateCnt.TitleFile(s)
4853heyh...7/5/20179579성태님이 작성한대로 해봤습니다. [1]파일 다운로드1
4852김레오7/4/201711759서드파티 dll 디버깅에 대해 질문드립니다. [2]
4851김현준7/3/201710865Datagridview VirtualMode 시 GC가 계속 호출되는 현상이 이해가 안갑니다. [2]
4850heyh...7/3/201710602성태님 밑에 질문드렸던 오류입니다. [1]파일 다운로드1
4849포플러7/2/201729276C#으로 만든 프로그램이 어느 순간 속도가 느려지거나 멈춤현상이 있습니다. [4]
4848윤진영7/2/201712251Microsoft Visual C++ 6.0 무설치 관련 [1]
4847heyh...6/30/201710261아무리 고민해도 답이 안나와서.. 질문 드립니다 [1]
4846heyh...6/28/201710301Clickonce에서 Clickonce로 변수 전달 [1]
4845heyh...6/26/20179973vb.net 에서 manifest 제거 방법 [1]파일 다운로드1
4844san6/21/20179402part3 pdf파일로 보는데 눈아퍼요.... 활자로 보고싶어요 [2]
4843윤현수6/20/20179636socket통신에 관한 질문입니다. [1]
4842오세운6/7/201710321로그인폼 다시 질문드려요. [1]
4841popo6/7/201710084궁금한사항이 있어 질문 드립니다. [1]
4840윤현수6/5/201710097datagridview에 바인딩시킨 dataset.table에 관련된 질문입니다. [2]파일 다운로드1
4839오세운6/2/201710997로그인폼 만들기 [1]
4838후배5/29/201711719PDF Reader 라이브러리.. [3]
4837KDP5/29/201711213c++ to C# 컨버팅 문의 [2]
4836popo5/26/201714358리플렉션 성능 관련 질문 드립니다. [2]
4835guest5/25/201710080wpf Canvas 질문드립니다. [1]
4834부탁드립...5/19/201710982익스체인지 서버 구동중 인증서를 받는 과정에서오류가 납니다 [1]
4833안종윤5/18/201711392winform을 Web Browser에 붙일 수 있는지요? [1]
4832guest5/17/201710859c# UDP socket예제 실행방법 [3]
4831guest5/15/201713337WPF .net 3.5에서 TextBox 한글 문제 [3]
4830초보자5/7/201718253프로그램 비정상 종료 메시지 창 없애는 방법 [4]
4829윤현수4/26/201714634System.Text.Encoding 질문 [1]
4828jaem...4/20/201710893시스템 종료시 block 함수 xp 지원가능한 방법 질문 [2]
... 31  32  33  34  35  36  37  38  39  [40]  41  42  43  44  45  ...