2010-11-29 4 views
2

멀티 스레드를 사용하는 서버 프로그램에서 작업하고 있습니다. 문제는 여러 클래스와 많은 스레드가 있으며 특정 TextBox에 모두 액세스해야한다는 것입니다.C# 다른 스레드에서 컨트롤 호출

using System; 
using System.Windows.Forms; 
using System.ComponentModel; 

namespace Server 
{ 
    public delegate void Logs(string message); 

    public partial class Menu : Form 
    {  
     public Menu() 
     { 
      InitializeComponent(); 
     } 

     public void Log(string message) 
     { 
      if (this.tbLog.InvokeRequired) 
       this.tbLog.BeginInvoke(new MethodInvoker(delegate() { tbLog.Invoke(new Logs(Log)); } 
      )); 
      else 
       this.tbLog.Text += DateTime.Now + ": " + message + Environment.NewLine; 
     } 
    } 
} 

당연히 내가 해봤 다른 일을하고, 이것은 나의 더 나은 시도 중 하나가 아닌 : (tbLog는)

방법 (로그인)이 같은 것 같습니다. 문제는 다른 스레드/클래스에서 다음과 같이 메서드를 호출하더라도 마찬가지입니다.

namespace Server.Connections 
{ 
    class packetSend 
    { 
     static bool sendPacket(string rawPacket) 
     { 
      Menu menu = new Menu(); 

      menu.Log("I'm a message"); 

      return true; 
     } 
    } 
} 

-it는 주 스레드에서만 작동합니다. 그리고 나는 그것이 네임 스페이스와 함께 할 수있는 뭔가가 생각이나 내가 사용하고 있기 때문에 :

Menu menu = new Menu(); 

대답은 아마도 분명하다,하지만 난 그것을 보이지 않아요.

도움말을 한숨 것은 매우 apreciated 될 것이다.

답변

3

왜 당신이 메시지를 로그인 할 때마다 새로운 형태를 만드는? 인보가 정상적으로 작동 방법

입니다 : 예와

  1. 응용 프로그램 시작시, 로그를 표시하는 양식을 작성합니다. 이것은 주 스레드에 있습니다. 당신이 로그인 할 필요가있을 때

  2. 그런 다음, 해당 양식에 대한 참조를 가져; 그런 다음

  3. Invoke, 당신은 그 형태에 로그를 보낼 수 있습니다.

즉석에서 양식을 작성해야하는 경우 Invoke을 사용하여 새 양식을 작성해야합니다. 기본 폼에 대한 참조를 가져 와서 해당 폼의 Invoke을 사용하여 폼을 만들 수도 있습니다. 당신이 메시지 루프가없는 비 UI 스레드에 Menu 양식을 작성하기 때문에

당신이보고있는 문제입니다.

+0

좋아요, 매번 새로운 양식을 만드는 대신 참조하기 만하면됩니다. 하지만 그렇게한다면 Log 메소드를 정적으로 만들어야 할 것입니다. 즉, Log 메서드에서 Menu라는 객체를 만들어야한다는 의미입니다 (현재). 그 문제를 해결하는 방법을 알고 있습니까? – Nick

+0

가장 중요한 점은 주 스레드와 통신 할 수있는 방법이 필요하다는 것입니다. 두 가지 옵션이 있습니다. 1. 메인 스레드에서'Menu' 폼을 만듭니다. 응용 프로그램을 시작할 때. 2. 즉석에서'Menu' 폼을 만들고 다른 폼, 아마도 메인 폼에서'Invoke'를 사용하십시오. 그리고 네,이 양식 중 하나에 대한 참조가 필요합니다. 정적 변수를 만들면됩니다. public static Menu Instance {get; 개인 집합; }'당신은 생성자'Instance = this;'에서 이것을 설정합니다. –

+0

고마워, 그 트릭을 했어! Menu.Instance.Log ("Message")를 호출 할 수 있는지 몰랐습니다. – Nick

0

대답은 생각보다 간단합니다 (당신은 답장이 없습니다, 그래서 항상 잘못된 스레드에서 실행). 코드를 약간 단순화 할 수 있습니다.

namespace Server 
{ 
    public delegate void Logs(string message); 

    public partial class Menu : Form 
    { 
     public Menu() 
     { 
      InitializeComponent(); 
     } 

     private void InitializeComponent() 
     { 
      throw new NotImplementedException(); 
     } 

     public void Log(string message) 
     { 
      if (InvokeRequired) 
      { 
       Invoke(new Action<string>(Log), message); 
       return; 
      } 
      else 
      { 
       this.tbLog.Text += DateTime.Now + ": " + message + Environment.NewLine; 
      } 
     } 
} 
관련 문제