2011-10-24 3 views
2

병렬로 실행되는 여러 개의 작업이있는 시스템을 설계하고 있습니다. 각각은 입력을 받아서 그래픽 출력을 벡터 형식으로 반환해야합니다. 벡터 형식의 그래픽을 한 스레드에서 다른 스레드로 반환하는 방법은 무엇입니까?

주 WPF 응용 프로그램은 사용자 요청시 이러한 작업의 결과를 그려야합니다. 현재 Canvas, Rectangle 및 기타 System.Windows.Shapes를 출력용 그래픽 벡터 형식으로 사용하고 있습니다. 작업이 완료되면 Canvas 하위를 가져와 GUI 실제 Canvas에 하나씩 추가합니다.

그러나 UI 요소를 주 스레드 (소위 Dispatcher 스레드) 이외의 다른 스레드에서 만들 수 없음을 발견했습니다. http://social.msdn.microsoft.com/Forums/ar/wpf/thread/c4600372-342c-4ee4-b49c-d9abf967fc93
사용자가 출력을 요청할 때마다 표시되어야하므로 UI ​​요소의 생성을 주 스레드로 위임하는 것은 나를위한 옵션이 아닙니다. 끝마친.

사실 저는 다른 스레드에서 UI 요소를 만들 필요가 없습니다. 벡터 그래픽을 만들고 나중에 WPF 응용 프로그램에서 나중에 표시하는 편리한 방법이 필요합니다.

누구에게 아이디어가 있습니까?

+0

당신은 하나 개의 스레드에서 그러한 직렬화는 필요할 때 UI 스레드에서 그들을 역 직렬화 할 수 있나요? – Rachel

+0

레이첼, 스레드에 항목을 만들어야하기 때문에 할 수 없습니다. 즉시 예외를 throw합니다. 물론, ** 문자열 ** XML을 만들고 메인 스레드에서 비 직렬화 할 수 있지만, 너무 번거 롭습니다. –

+0

표시 할 내용을 설명하는 * 작업을 수행 한 다음 UI 스레드에서 결과 요소를 만들어야합니다. 예를 들어 실제 S.W.S.Rectangle을 만드는 대신 더 많은 정보 (x, y, transforms 등)로 Rect를 만들고이 정보로 실제 Rectangle을 생성 할 수 있습니다. – Will

답변

0

나는 다른 가능한 답을 찾았습니다. 필자의 경우처럼 그래픽이 그려지지 않고 오히려 정의 될 때 Shapes 대신 GeometryDrawing 클래스를 사용해야합니다. Freeze 메서드가 있습니다.이 메서드는 변경할 수 없으므로 다른 스레드를 통해 전달할 수 있습니다. 는 마이크로 소프트 MSDN에서 발췌 :

System.Windows.Shapes.Shape 클래스는 기하학과 그 파생 클래스가 부족 채우기, 뇌졸중 및 기타 렌더링 속성이 있습니다. Shape 클래스는 FrameworkElement이므로 레이아웃 시스템에 참여합니다. 파생 클래스는 UIElement 자식을 지원하는 요소의 내용으로 사용할 수 있습니다.

반면에 기하학 클래스는 단순히 모양의 기하 도형을 정의하며 자체 렌더링 할 수 없습니다. 단순함으로 인해 더 넓은 범위의 용도가 있습니다.

MSDN reference

1

병렬 활동을 시작하기 전에 UI (주 스레드) SynchronizationContext을 캡처하십시오. 그리고 (필요할 때마다) Send 메서드를 호출하여 메시지를 UI 스레드로 푸시 (push)하기 위해 SynchronizationContext 참조로 캡처하십시오. MSDN on SynchronizationContext

public partial class MainWindow : Window 
    { 
     SynchronizationContext UISyncContext; 
     YourTaskOutPut Myresult; 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 
     public StartProcessingVGraphics() 
     { 
      //Let say this method is been called from UI thread. i.e on a button click 
      //capture the current synchronization context 

      UISyncContext=TaskScheduler.FromCurrentSynchronizationContext; 

      //Start your VGraph processing using TPL in background and store result to Myresult (of type YourTaskOutPut) 
      result= GetMeTaskResults(); 

     } 

     public GetMeResultNow() 
     { 
      //Let's say this is is the method which user triggers at 
      //some point in time (with the assumption that we have Myresult in hand) 

      if(UISyncContext!=null) 
       UISyncContext.Send(new SendOrPostCallback(delegate{ PutItInUI }),null); 

      //Use Send method - to send your request synchronously 
      //Use Post method- to send your request asynchronously 
     } 
     void PutItInUI() 
     { 
      //this method help you to put your result in UI/controls 
     } 
+0

http://www.codeproject.com/KB/cpp/SyncContextTutorial.aspx를 찾았습니다. 더 나은 설명이 있습니까? –

관련 문제