经过长时间学习WCF,于是和大家分享一下,看完本文你肯定有不少收获,希望本文能教会你更多东西。由于WCF回调方法并非运行在主线程中,如果WCF回调方法需要更新与异步调用结果相关的界面,例如本例中的lbMessage控件,则需要将回调的调用封送(Marshal)到当前主程序界面的同步上下文中。我们可以使用 SynchronizationContext以及它的SendOrPostCallback委托,对调用进行封送:
public ExplorerClientForm()
{
InitializeComponent();
m_synchronizationContext = SynchronizationContext.Current;
}
private SynchronizationContext m_synchronizationContext;
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
则WCF回调方法修改为:
//callback method
void OnTransferCompleted(IAsyncResult result)
{
Stream stream = m_service.EndTransferDocument(result);
result.AsyncWaitHandle.Close();
SendOrPostCallback callback = delegate
{
lbMessage.Text = string.Format("The file {0} had been transfered sucessfully.",
m_doc.FileName);
};
m_synchronizationContext.Send(callback,null);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
#T#在调用异步方法时,由于对BeginTransferDocument()和EndTransferDocument()方法的调用可能会在不同的方法体中,因而我将服务代理对象定义为private字段。如果希望将服务对象定义为一个局部变量,可以在调用BeginTransferDocument() 方法时,将代理对象传递到方法的asyncState参数中,然后在调用EndTransferDocument()方法之前,通过 IAsyncResult获得准确的服务代理对象:
m_service.BeginTransferDocument(m_doc,OnTransferCompleted,m_service);
- 1.
将m_service作为asyncState对象传入之后,在调用EndTransferDocument()方法之前,就可以根据它先获得服务代理对象:
IDocumentsExplorerService m_service = result.AsyncState as IDocumentsExplorerService;
Stream stream = m_service.EndTransferDocument(result);
//rest codes
- 1.
- 2.
- 3.