Microsoft MVP성태의 닷넷 이야기
[C# 6.0]multi threading과 ui control [링크 복사], [링크+제목 복사]
조회: 11521
글쓴 사람
힘찬도약 (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)
4826김솔지4/11/20179992CxImage 문자 출력 [1]
4825플메4/10/201710376덱스트 업로드 하는데 구성요소 서비스에 엑셀이 안뜨네요..ㅜㅜ [1]파일 다운로드1
4824김상경4/9/20179768win7에서 vb6.0을 이용해서 프로그램을 만들었습니다.(제가 만든건 아니고 옆 동료가 만들었습니다.) [1]파일 다운로드1
4823조상현3/28/201710800windows event log 에 대한 정보는 어디서 얻을 수 있을까요? [1]
4822부우3/24/201712455글수정이 안되어 다시올려드립니다ㅠ [12]파일 다운로드2
4821부우3/22/201726071파일이나 어셈블리 중 하나를 로드에러 좀 봐주세요 [9]파일 다운로드1
4820듀이3/20/201710883오차 없이 동시에 명령을 보내게 가능한가요? [2]파일 다운로드1
4819popo3/20/201712228C# sslstream 사용시 Cipher List 설정 [3]
4818부우3/16/201721088DllImport 사용시 진입점을 찾을수 없습니다 [2]
4817yun3/15/201710447서피스프로4의 HYPER-V로 윈도우7을 깔았는데... [1]
4816부우3/15/201713190C++ DLL함수 사용 질문드립니다 [10]
4815김지용3/14/20179256.net core linux 오류 [2]
4814김솔지3/13/201710325인쇄 시 , 출력화면을 이미지 파일로 저장하고 싶습니다. [1]파일 다운로드1
4813spow...3/8/201711867멀티 스레드 환경에서 처리하여야 할 목록을 효율적으로 사용하는 기법 질문 드립니다 [2]
4812popo2/23/201711936.NET Window ClassName 변경 질문 드립니다. [1]
4809힘찬도약2/15/201714999C# 가상 시리얼 [4]
4808이길용2/9/201713748WCF 외부 접속 관련해서 질문드립니다ㅠ [1]
4807헬조선식...2/8/201720325WPF의 속도에 대해서 궁금합니다. [3]
4803헬조선식...2/7/201713747WPF로 메신져 메세지 박스 구현 문의 [2]
4802spow...2/6/201710781특정 범위의 값을 다른 값으로 치환하는 메소드를 만들어야 할 때 가장 빠른 방법은? [7]
4804spow...2/7/201710651    답변글 [답변]: 특정 범위의 값을 다른 값으로 치환하는 메소드를 만들어야 할 때 가장 빠른 방법은?
4805spow...2/7/201710329    답변글 [답변]: 특정 범위의 값을 다른 값으로 치환하는 메소드를 만들어야 할 때 가장 빠른 방법은? (글삭제가 안돼 재첨부합니다)파일 다운로드1
4801spow...2/3/201710208C#의 참조 동작관련하여 아이디어 문의 드립니다 [4]
4800오세운2/1/201714273C# 에서 C++ DLL임포트 질문입니다. [2]
4798guest1/29/201711631picturebox의 image.dispose [1]
4797김철환1/13/201711563책에 관한 질문입니다 [3]
... 31  32  33  34  35  36  37  38  39  40  [41]  42  43  44  45  ...