2009-10-23 5 views
0

다른 세트가 아닌 일련의 창에서 액세스 할 수있는 컨텍스트를 만들 수 있습니까?액세스 할 수있는 컨텍스트를 만드는 방법은 무엇입니까?

예를 들어 두 개의 웹 요청이 자신의 컨텍스트에서 실행되고 ServiceSecurityContext.Current과 같은 개체가 다른 인스턴스를 가리키고 있습니다.

내 신청서는 계획서를 여는 PlanWindow과 같은 Word 응용 프로그램입니다. 이 PlanWindow에서 열리는 모든 대화 상자로 문서를 전달하지 않고 현재 계획을 반환하는 PlanContext.Current과 같은 작업을 수행 할 수 있기를 원합니다.

나는 이것이 스레딩과 관련이 있다고 생각하지만 어디서부터 시작해야할지 모르겠다.

+0

ParentForm 참조를 ChildForm에 전달하는 것은 비합리적인 일이 아닙니다.그런 다음 ParentForm의 공용 속성을 원하는대로 확인할 수 있습니다. – Greg

+0

"PlanContext.Current"는 어디에서 호출하려고합니까? 그것은 귀하의 GUI 개체 (UserControls 및 양식)에만 있습니까? –

답변

1

나는 내 프로젝트 중 하나에서 비슷한 문제를 다루었 다. 나는 GetDataSetData 방법을 System.Runtime.Remoting.Messaging.CallContext으로 사용했습니다.

CallContext는 각 스레드에 고유하며 스레드와 관련된 개체를 저장하는 데 사용할 수 있습니다. 이 특정 시나리오에서

는,이 같은 PlanContext 클래스를 만들 것이다 :
public class PlanContext 
{ 
    const string _PlanDocumentSessionKey = "Current_PlanDocument"; 
    public static PlanDocument Current 
    { 
     get 
     { 
      return CallContext.GetData(_PlanDocumentSessionKey) as PlanDocument; 
     } 
     set 
     { 
      CallContext.SetData(_PlanDocumentSessionKey,value); 
     } 
    } 
} 

그리고 문서를 인스턴스화 코드

는이를 추가

PlanContext.Current = newDocument; 

참고로, HttpContext.Current도 CallContext를 사용하여 특정 스레드에 대한 컨텍스트를 검색합니다.

+0

Winform 컨텍스트에는 단일 GUI 스레드가 1 개 있습니다. CallContext를 사용하면 항상 동일한 PlanDocument를 반환합니다 ... 따라서 이것은 PlanContext 클래스의 Current라는 정적 속성과 동일합니다. 또는 나는 무엇인가 놓치고 있냐? –

+0

그가 단일 스레드를 사용할 계획이라면 정적 변수는 정상적으로 작동합니다. 하지만 그는 자신이 작성한 PlanWindow 각각에 대해 여러 스레드를 사용하려고한다고 가정했습니다 (시나리오를 두 번의 웹 요청과 비교했기 때문에). 개인적으로, 여러 스레드를 사용하는 것이 모달 대화 상자 (인쇄 대화 상자라고 부름) 중 하나에서 열린 대화 상자가 다른 문서의 입력을 차단하지 않기 때문에 더 나은 방법이라고 생각합니다. – madaboutcode

0

정적 사전? PlanContext [세션 ID]?

+0

하지만 그렇게되면 SessionId를 가지고 다니게 될 것입니다. 모든 양식과 객체에 가치를 전달하려면 문서 자체 여야합니다. –

0

저는 이것을 한 번도 해본 적이 없기 때문에 올바른 방향으로 가리킬 수 있습니다. 어떻게 두 번째

http://msdn.microsoft.com/en-us/library/ms157901.aspx

, 여기 :

첫째, 여기에 자신의 스레드에서 각각, 윈도우가 양식 응용 프로그램에서 여러 "주"창을 만들기 위해 두 개의 스레드에서 Application.Run을 사용하는 방법 이 당 스레드 상태 :

How does HttpContext.Current work in a multi-threaded environment?

http://blogs.msdn.com/jfoscoding/archive/2006/07/18/670497.aspx

0

이것이 스레딩과 아무런 관련이 없다고 생각합니다.

Current에 의해, 당신은 Selected or Active Plan을 의미하는 경우에, 당신이 선택한 계획을 추적하는 PlanWindow 객체에 Property을 설정할 수 있습니다 (예 : 다른 계획이 선택 될 때마다 활성화/업데이트)이 속성은 다른 모든 창에 액세스 할 수 있습니다/대화 상자 (예 : 그것은 정적 확인)

1

방법은 다음과 같은 아키텍처이 해결에 대한 :

IPlanContextReceiver 
{ 
    public object StateByWichPlanContextCanDeciceWhatToReturn get; 
} 

class SomeWindow : Window, IPlanContextReceiver 

그리고 PlanContext에서

대신 현재 속성은이

0123가
public static PlanContext GetCurrent(IPlanContextReceiver receiver) 
{ 
    lock(contextSync) // be threadsafe if necessary 
    { 
     if(/*condition that checks receiver.StateByWichPlanContextCanDeciceWhatToReturn*/) 
     { 
      // context is valid for this receiver 
      // return the correct context from an internal store or similar 
      return Contexts["TheContextForCoolReceivers"]; 
     } 
     else if(/*condition that checks receiver.StateByWichPlanContextCanDeciceWhatToReturn*/) 
     { 
      // context is valid for this receiver 
      // return the correct context from an internal store or similar 
      return Contexts["TheContextForUncoolReceivers"]; 
     } 

     // no existing context is available for this receiver 
     return null; 
    } 
} 

다시 싱글 톤으로 만들면 GetCurrent도 인스턴스 메서드가 될 수 있습니다. 그리고 방법 대신에 그것은 인덱서가 될 수도 있습니다. 그것은 맛의 문제입니다.

또한 실제로는 StateByWichPlanContextCanDeciceWhatToReturn의 실제 내용입니다. 검사해야 할 여러 속성만큼 복잡 할 수도 있고 창 컨텍스트 그룹마다 한 번만 설정하는 문자열처럼 간단 할 수도 있습니다.

0

나는 C를 사용하지 않지만 자바에서는 java.lang.ThreadLocal을 사용합니다.

public class MyClass { 

    private static ThreadLocal<MyClass> instance = new ThreadLocal<MyClass>() { 
     protected View initialValue() { 
      return null; 
     } 
    }; 

    private MyClass(Object arg1, Object arg2) { 
     this.arg1 = arg1; // Web request? 
     this.arg2 = arg2; // Web response? 
    } 

    public static MyClass getInstance() { 
     return instance.get(); 
    } 

    public static MyClass createInstance(Object arg1, Object arg2) { 
     MyClass myClass = new MyClass(arg1, arg2); 
     setInstance(myClass); 
     return myClass; 
    } 

    protected static void setInstance(MyClass myClass) { 
     if (myClass == null) { 
      instance.remove(); 
     } else { 
      instance.set(myClass); 
     } 
    } 

    public void release() { 
     setInstance(null); 
    } 

} 

createInstance()은 처음 생성 될 때 호출됩니다. 그런 다음 동일한 스레드를 계속 실행하면서 원하는 순간마다 getCurrentInstance()으로 전화 할 수 있습니다.

C. 유사한 행운이 있는지 확인하십시오.

0

먼저 MDI Windows Form 응용 프로그램이라고 가정하고 각 하위 창은 사용자에게 문서를 표시합니다. 이 인터페이스

1) 깃발 모든 창 (자식 창) :

public interface IPlanViewer { //this means that all you windows will have this property PlanDocument Document { get; } } 

2

)은 "컨텍스트"를 만들기 클래스

public class Context 
{ 
    public static Context Current { get; set; } 
    static Context() 
    { 
     Current = new Context(); 
    } 

    //The key method : I'm returning the document of the currently selected child windows or null if no windows are opened 
    public PlanDocument Document 
    { 
     get { 
      var currentView = Form.ActiveForm as IPlanViewer; 
      if (currentView != null) 
       return currentView.Document; 
      else 
       return null; 
     } 
    } 
} 

3)이 컨텍스트를 사용하여 like this

그게 전부입니다. 이게 당신을 도울 수 있기를 바랍니다.

Manitra.

+0

Form.ActiveForm을 사용할 때의 문제점은 대화 상자에있는 경우 IPlanViewer가 아니라 현재 활성 양식입니다. –

+0

안녕하세요, 피에르 알랭, 귀하의 문제를 이해했습니다. 방금 더 나은 답변을 제출했습니다. –

1

그래서 여기입니다 활성 형태의 대화 상자 경우에도 다른 제안 느릅 나무 작업 :

1) 깃발 모든 창 (자식 창)이 인터페이스 :

public interface IPlanViewer 
{ 
    //this means that all you windows will have this property 
    PlanDocument Document { get; } 
} 

2)은 "컨텍스트"클래스를 만듭니다

public class Context 
{ 
    public static Context Current { get; set; } 
    public IPlanDocument Document { get; set; } 
    static Context() 
    { 
     Current = new Context(); 
    } 
} 

3)에서 MDI 폼이 방법

private void MdiForm_MdiChildActivate(object sender, EventArgs e) 
{ 
    var currentView = Form.ActiveForm as IPlanViewer; 
    if (currentView != null) 
     Context.Current.Document = currentView.Document; 
} 

4)을의이

private void WorkWithCurrentDoc() 
{ 
    var doc = Context.Current.Document; 
    doc.Title = "totot" 
    // etc ... 
} 

처럼이 컨텍스트를 사용으로 MdiChildActive 이벤트를 처리합니다. 더 나아 졌습니까?

Manitra.

관련 문제