代表和WCF方法

Pet*_*ter 4 wcf delegates

我已经使用WCF成功设计了一个大型文件上传方法.现在,我想报告正在加载的每个唯一文件的进度.在我的上传方法中,我有以下代码块:

while ((bytesRead = request.FileByteStream.Read(buffer, 0, bufferSize)) > 0)
{
    outfile.Write(buffer, 0, bytesRead);
    totalBytesRead += bytesRead; 

    if (this.ProgressChanged != null)
        this.ProgressChanged(this, new ProgressArgs(totalBytesRead, request.FileByteStream.Length)); 

}
Run Code Online (Sandbox Code Playgroud)

其中使用了Deleget ProgressEventHandler,如下所示:

public delegate void ProgressEventHandler(object sender, ProgressArgs e);
public event ProgressEventHandler ProgressChanged; 
Run Code Online (Sandbox Code Playgroud)

我不会那么多地使用代表(但我正在努力学习)并通过在线跟踪示例来实现这一目标.示例中缺少ProgressArgs类,但我猜这是计算发生的地方并返回?像这样的东西:return Convert.ToInt32((totalBytesRead * 100) / fileSize)

所以,我的问题是:

1)假设我已正确声明并调用了我的ProgressChanged事件,我该怎么处理ProgressArgs

2)如何向客户报告进度?我的WCF方法调用当前具有'void'返回类型:

upload.UploadFile(fileinfo,m_objFile.InputStream);

我是否需要触发同时调用WCF JSON方法或类似性质的JavaScript方法?关于如何从客户端查看进度的详细说明将受到重视.

谢谢!

PS - 我正在使用ASP.NET 2.0/Framework 3.5/C#/我目前正在自托管.

Dre*_*rsh 6

哇,你在一个问题中询问了很多不同的层.

回调,而不是事件

您正在尝试执行特定于.NET的操作,而不是直接映射到Web服务编程.您不能在Web服务中使用事件/委托.相反,你必须定义所谓的"回调合约".这是另一个界面,其上有方法,表示您想要告诉调用者的通知,并应用于您的服务合同,如下所示:

public interface MyCallbackContract
{
    void ProgressChanged(float percentComplete);
}

[ServiceContract(CallbackContract = typeof(MyCallbackContract)]
public interface MyServiceContract
{
    void UploadFile(Stream stream);
}
Run Code Online (Sandbox Code Playgroud)

现在,回调契约需要双向(双工)通信,因此,如果您现在只是使用basicHttpBinding,则需要切换到使用wsDualHttpBinding或一些非http绑定,这会将此服务的互操作吹出水面.假设您的服务完全是Intranet,那么这不应该是一个showstopper.

关于回调编程模型还有很多东西需要学习,我不会在这里讨论.相反,我将向您推荐Juval Lowey撰写的一篇精彩的MSDN文章,文章详细介绍了该主题.

这对我在浏览器中有什么帮助?

问题的第二部分是如何从浏览器中获取此信息,首先,我们必须接受它绝对没有办法直接与提供的服务进行通信.相反,您需要构建一个AJAX"桥接"服务.由于浏览器是纯HTTP,因此您必须使用POST将文件上载到基于REST的WCF服务.如果您想同时检索有关该上传的状态,则必须进行轮询请求以获取状态.

老实说,这是浏览器仍然只是作为平台糟糕的地方之一.浏览器知道它发送了多少数据,你应该能够基于此报告进度,但它不会在任何地方暴露.这就是为什么人们转向使用基于Flash的上传实用程序的原因,因为Flash确实公开了这些细节,因此您无需轮询服务器以获得进展.