2009-12-02 2 views
2

wm_paint와 같은 기본 메시지가 처리되면 WCF Webservices 호출이 트리거됩니다 (예 : 원격 서식 정보가 필요한 경우).동기 호출에서 대기하는 동안 WCF가 메시지 펌핑을 중단하는 방법은 무엇입니까?

그러나 WCF가 해당 호출이 반환 될 때까지 기다리는 동안 메시지는 계속 펌핑되고 ​​다른 호출은 동일한 호출을 트리거합니다.

-Thread 안전성은 "가짜"다중 스레드이므로 내 문제에 도움이되지 않습니다. 항상 동일한 스레드가 펌프의 메시지를 해석합니다.

- 두 번째 호출에 올바르게 실행하려면 원격 정보가 필요하기 때문에 재방송 안전은 도움이되지 않습니다.

는 다음 (간체) 호출 스택 참조 :

MyService.DoSomething(System.String) 
    [...] 
    Grid.OnPaint(System.Windows.Forms.PaintEventArgs) System.Windows.Forms.Control.PaintWithErrorHandling(System.Windows.Forms.PaintEventArgs, Int16, Boolean) 
    System.Windows.Forms.Control.WmPaint(System.Windows.Forms.Message ByRef) 
    System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message ByRef) 
    System.Windows.Forms.ContainerControl.WndProc(System.Windows.Forms.Message ByRef) 
    System.Windows.Forms.Control+ControlNativeWindow.OnMessage(System.Windows.Forms.Message ByRef) 
    System.Windows.Forms.Control+ControlNativeWindow.WndProc(System.Windows.Forms.Message ByRef) 
    System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr) 
    System.Threading.WaitHandle.WaitOneNative(Microsoft.Win32.SafeHandles.SafeWaitHandle, UInt32, Boolean, Boolean) 
    System.Threading.WaitHandle.WaitOne(Int64, Boolean) 
    System.Threading.WaitHandle.WaitOne(Int32, Boolean) 
    System.Net.LazyAsyncResult.WaitForCompletion(Boolean) 
    System.Net.Connection.SubmitRequest(System.Net.HttpWebRequest) 
    System.Net.ServicePoint.SubmitRequest(System.Net.HttpWebRequest, System.String) 
    System.Net.HttpWebRequest.SubmitRequest(System.Net.ServicePoint) 
    System.Net.HttpWebRequest.GetRequestStream(System.Net.TransportContext ByRef) 
    System.Net.HttpWebRequest.GetRequestStream() 
    System.ServiceModel.Channels.HttpOutput+WebRequestHttpOutput.GetOutputStream() 
    System.ServiceModel.Channels.HttpOutput.Send(System.TimeSpan) 
    System.ServiceModel.Channels.HttpChannelFactory+HttpRequestChannel+HttpChannelRequest.SendRequest(System.ServiceModel.Channels.Message, System.TimeSpan) 
    System.ServiceModel.Channels.RequestChannel.Request(System.ServiceModel.Channels.Message, System.TimeSpan) 
    System.ServiceModel.Channels.SecurityChannelFactory1+SecurityRequestChannel[[System.__Canon, mscorlib]].Request(System.ServiceModel.Channels.Message, System.TimeSpan) 
    System.ServiceModel.Dispatcher.RequestChannelBinder.Request(System.ServiceModel.Channels.Message, System.TimeSpan) 
    System.ServiceModel.Dispatcher.ProxyOperationRuntime, System.Object[], System.Object[], System.TimeSpan) 
    System.ServiceModel.Dispatcher.ProxyOperationRuntime, System.Object[], System.Object[]) 
    System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(System.Runtime.Remoting.Messaging.IMethodCallMessage, System.ServiceModel.Dispatcher.ProxyOperationRuntime) 
    System.ServiceModel.Channels.ServiceChannelProxy.Invoke(System.Runtime.Remoting.Messaging.IMessage) 
    System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(System.Runtime.Remoting.Proxies.MessageData ByRef, Int32) 
    [...] 
    MyService.DoSomething(System.String) 
    [...] 
    System.Windows.Forms.Control.WmMouseUp(System.Windows.Forms.Message ByRef, System.Windows.Forms.MouseButtons, Int32) 
    System.Windows.Forms.Control.WndProc(System.Windows.Forms.Message ByRef) 
    System.Windows.Forms.Control+ControlNativeWindow.WndProc(System.Windows.Forms.Message ByRef) 
    System.Windows.Forms.NativeWindow.Callback(IntPtr, Int32, IntPtr, IntPtr) 
System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG ByRef) 
System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32) 
    System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext) 
    System.Windows.Forms.ApplicationContext) 
    System.Windows.Forms.Application.Run(System.Windows.Forms.Form) 
    [...] 
    MyApplication.Main() 

내가 호출 스택의 상단을 절단했습니다,하지만이 라인 MyService.DoSomething (시스템의 존재에 의해 어디로 가는지를 알 수 있습니다. String)을 호출 스택에서 두 번 호출합니다.

여기 어딘가에 System.Threading.WaitHandle.WaitOne (Int64, Boolean)이 호출되어 있습니다.

두 번째 매개 변수 (exitSynchronisationContext)에 대해 "true"로 전달되어 메시지 펌프가 펌핑을 유지할 수 있습니다.

WCF에서이 기본 동작을 피할 수있는 방법이 있습니까?

+0

나는 WaitOne이 문제라는 것이 맞다고 생각합니다. http://stackoverflow.com/questions/896233/how-to-wait-on-waithandle-without-message-pumping을 참조하십시오. –

답변

2

WM_PAINT !?에 대한 응답으로 WCF 호출을 호출하고 있습니다. 그것은 나에게 꽤 무섭다. :/

메시지 펌프를 강제로 멈출 수있는 경우에도 통화가 완료되는 동안 응답이없는 GUI가 표시됩니다. 네트워크 시간 초과 또는 호출에 몇 초가 걸리는 다른 이유가 있으면 어떻게해야합니까?

정보를 사전로드 할 수 없습니까? 또는 최소한의 게으른로드에서 WCF 호출은 한 번만 호출됩니다. 이 방법을 사용하면 load 메서드에 플래그를 설정하여 호출이 이미 진행 중인지 여부를 나타낼 수도 있습니다.

관련 문제