WCF comprehensive use: Large file asynchronous breakpoint continuation

Source: Internet
Author: User


The upload of large files in WCF, the first thought of using the stream, which is the Microsoft recommended use. The process is to first load the file into memory and pass the data after loading. This processing method for small files, it is recommended, such as a few k, dozens of k picture files, text files on large files do not apply, such as 10G movies, 10G of data loaded into the cache and then passed, it is unthinkable. At this point, we think of the continuation of the breakpoint. Because the amount of data is large. Will cause the current program to block, so the asynchronous send to the progress bar display, which is the function of this article to achieve. In addition, currently basichttpbinding, NetTcpBinding, and netnamedpipebinding support stream processing models, others are not supported, which also affects the use of stream.
Explain several important concepts and how to implement them:
1, the breakpoint continues to pass: it is in the last download/upload disconnected location to start downloading/uploading. Microsoft has provided a good way to do this: BinaryWriter This is a binary writer, see below:

Namespace System.IO
{
public class Binarywriter:idisposable
{
Public virtual long Seek (int offset, seekorigin origin); Sets the position in the current stream, the first parameter represents an offset, and the second parameter represents the reference for the offset
public virtual void Write (byte[] buffer); Write data to the location of the Seek method settings
}
}

2, asynchronous thread: is the use of background programs, do not block the current thread, using BackgroundWorker build, can greatly reduce the amount of code written
The following actions are part of the WCF-related section. First we define a data contract to pass the data:

[DataContract]
public class FileInfo
{
Filename
[DataMember]
public string Name {get; set;}

File byte size
[DataMember]
Public long Length {get; set;}

The offset of the file
[DataMember]
Public long Offset {get; set;}

Number of bytes passed
[DataMember]
Public byte[] Data {get; set;}

Creation time
[DataMember]
Public DateTime createtime {get; set;}
}

Then define the contract for the operation:

[ServiceContract]
public interface Ifilesload
{
[OperationContract]
List<fileinfo> getfileslist (); Get a list of files that have been uploaded
[OperationContract]
FileInfo GetFiles (string fileName); Returns the file's byte length, depending on the file name.
[OperationContract]
FileInfo uplodafile (FileInfo file); Uploading files
}

Define the contract, the following is to implement the contract, here just paste the important part, in the later can download the source code

Public Fish.DataContracts.FileInfo uplodafile (Fish.DataContracts.FileInfo file)
{
String filePath = system.configuration.configurationmanager.appsettings["FilePath"] + "/" + file. name;//gets the path to the file, the filename that has been saved
FileStream fs = new FileStream (FilePath, FileMode.OpenOrCreate);//Open File
Long offset = file.  Offset; File. Offset file offsets the position at which the subsequent data is added from this location
BinaryWriter writer = new BinaryWriter (fs);//Initialize file writer
Writer. Seek ((int) offset, seekorigin.begin);//Set the write location of the file
Writer. Write (file. data);//write
File. Offset = fs. length;//returns the file location after appending data
File. Data = null;
Writer. Close ();
Fs. Close ();
return file;
}

The following is a service-side WCF configuration

<system.serviceModel>
<services>
<!--file breakpoints to continue--
<service behaviorconfiguration= "Defaultbehavior" name= "Fish.ServiceImpl.FilesService" >
<endpoint address= "" binding= "basichttpbinding" bindingconfiguration = "streamedhttp" contract= " Fish.ServiceInterfaces.IFilesLoad "></endpoint>
<baseAddresses>
<add baseaddress= "Http://localhost:8080/Fish/FilesService"/>
</baseAddresses>
</service>
</services>

<behaviors>
<serviceBehaviors>
<behavior name= "Defaultbehavior" >
<servicemetadata httpgetenabled= "true"/>
<servicedebug includeexceptiondetailinfaults= "true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name= "streamedhttp" maxreceivedmessagesize= "2000000000000" messageencoding= "Mtom" transferMode= " Streamed ">
<readerquotas maxarraylength= "20000000"/>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>

The most wanted here is to set the maxreceivedmessagesize,messageencoding. It is more important to set to MTOM, which can increase the efficiency of 30%, which is specifically provided by WCF for large files. See the client code below:

var Filemanger = common.servicebroker.findservice<ifilesload> (); Create a WCF Proxy
String LocalPath = E.argument As String;
String fileName = localpath.substring (localpath.lastindexof (' \ \ ') + 1);//Get file Local file address
int maxsiz = 1024 * 100; Set 100k per Pass
FileStream stream = System.IO.File.OpenRead (LocalPath); Read local file
Fish.DataContracts.FileInfo file = Filemanger.getfiles (fileName); More file names, querying the service for the existence of the file
if (file = = NULL)//indicates that no files exist
{
File = new Fish.DataContracts.FileInfo ();
File. Offset = 0; Setting up files for data transfer from the start location
}
File. Name = FileName;
File. Length = stream. Length;
if (file. Length = = file. Offset)//If the length of the file is equal to the file offset, the file has been uploaded and completed
{
MessageBox.Show ("The file is already in the server, do not upload!") "," hint ", MessageBoxButtons.OK, messageboxicon.warning);
Return
}
Else
{
while (file. Length! = file. Offset)//loop read file, upload, until the length of the file equals the offset of the file
{
File. Data = new Byte[file. Length-file. Offset <= Maxsiz? File. Length-file. Offset:maxsiz]; Set the size of the data passed
Stream. Position = file. Offset; To set the read location for local file data
Stream. Read (file. Data, 0, file. DATA.LENGTH);//write data to file. Data in
File = filemanger.uplodafile (file); Upload

E.result = file. Offset;
(sender as BackgroundWorker). ReportProgress ((int) ((double) file. Offset/(Double) ((long) file. Length)), file. Offset);
if (this.backgroundWorker1.CancellationPending)
Return
}
}
Stream. Close ();
Common.servicebroker.disposeservice<ifilesload> (Filemanger); Close WCF

Finally, the result is the last run:


Code Address:/files/wanqiming/upload.rar

Original link: http://www.cnblogs.com/wanqiming/archive/2009/09/22/1571565.html

WCF comprehensive use: Large file asynchronous breakpoint continuation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.