簡體   English   中英

C#POCO到Stream / Byte []並在通過WCF用Silverlight 4客戶端讀取時進行處理

[英]C# POCO to a Stream/Byte[] and process while reading with a Silverlight 4 client over WCF

對我來說,Silverlight令人討厭的部分之一是它不允許您直接返回Stream ,因為即使使用TransferMode.StreamedResponse ,Silverlight也會將其轉換為Byte[] 使用該技術,可以從Silverlight客戶端以流方式處理FileStream類的東西( 請參見下面的代碼 )。

但是,我想對大型C#POCO做類似的事情。 如果可以接收Stream ,則可以在兩端使用XML序列化之類的東西,並在讀取記錄時對其進行處理。 但是,由於返回值必須是Byte[] ,因此必須先讀取數組的末尾才能處理它。 這種方法至少確實允許我向用戶提供一些反饋。

我提出了兩種可能的解決方案。 一種方法是編寫我自己的序列化程序,或至少是反序列化程序,在讀取數據時在其中處理數據(我在考慮分隔文本)。 另一個想法是做某種類型的可變位Stream類,我認為這需要我的陡峭學習曲線。 我正在尋找有關如何處理讀取Byte[]中的值的任何想法或鏈接。

服務合同:

public static class Action {
    public static string val = "http://tempuri.org/stream";
}

// Share contract between client and server
[ServiceContract]
public interface IFileService {
#if SILVERLIGHT
    [OperationContract(AsyncPattern = true, Action = Action.val, ReplyAction = Action.val)]
    IAsyncResult BeginReadFile(Message request, AsyncCallback callback, object AsyncState);
    system.ServiceMode.Channels.Message EndReadFile(IAsyncResult result);
#else
    [OperationContract(AsyncPattern = true, Action = Action.val, ReplyAction = Action.val)]
    IAsyncResult BeginReadFile(string filePath, AsyncCallback callback, object AsyncState);
    system.IO.Stream EndReadFile(IAsyncResult result);
#endif
}

[DataContract(Name = "ReadFile", Namespace = "http://tempuri.org/")]
public class StreamRequest
{
    [DataMember(Order = 1)]
    public string FileName;
}

服務實施:

public IAsyncResult BeginReadFile(string filePath, AsyncCallback callback, object AsyncState) {
    return new CompletedAsyncResult<Stream>(File.OpenRead(filePath));
}

public Stream EndReadFile(IAsyncResult result) {
    return ((CompletedAsyncResult<Stream>)result).Data;
}

客戶:

public void ReadFile( string filePath ) {
    BackToUIThread backToUIThread = byteCount => {
        this.OnBytesReceived(this, new AsyncEventArgs<object>(byteCount));
    };

    StreamRequest request = new StreamRequest() { FileName = "C:\\test.txt" };
    Message mIn = Message.CreateMessage(
        _myFactory.Endpoint.Binding.MessageVersion, Action.val, request);

    _myService.BeginReadFile(mIn,
        (asyncResult) =>
        {
            Message mOut = _myService.EndReadFile(asyncResult);
            System.Xml.XmlDictionaryReader r = mOut.GetReaderAtBodyContents();
            r.ReadToDescendant("ReadFileResult"); // move to stream
            r.Read(); // move to content

            int bytesRead = 1;
            long totalBytesRead = 0;
            byte[] buffer = new byte[100];
            do {
                bytesRead = r.ReadContentAsBase64(buffer, 0, buffer.Length);
                totalBytesRead += bytesRead;
                if (bytesRead > 0) {
                    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(
                        backToUIThread, totalBytesRead);
                }
            } while (bytesRead > 0);
            r.Close();
            mOut.Close();                
        }, null);
}

您可以讓Silverlight應用程序輸入偏移量和要讀取到服務中的字節數。

你可能會喜歡

int offset = 0;  
int length = 1024;  
List<byte> bytes = new List<bytes>();  

_myService.ReadFileComplete += (s, e)=>  
{  
    bytes.Add(e.Result.Bytes);  
    if(asyncResult.Result.HasMore)  
    {  
        offset += length;  
        _myService.ReadFileAsync(fileName, offset, length);  
    }  
    else  
    {  
        DoSomethingWithBytes(bytes);  
    }  
}

_myService.ReadFileAsync(fileName, offset, length);

然后在WCF服務上,僅使用具有給定偏移量和長度的Stream.Read方法。

您可以通過使服務返回要讀取的下一個偏移量來改善此問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM