[英]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.