1

WCF を使用してファイル ストレージを作成することを考えました。インターネットで検索し、多くの例を見つけて、彼のサービスを作成しました。

namespace CTFileStorage
{
 [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    interface CTIFileStorageClass
    {
            [OperationContract]
            CTFileName UploadStream(CTRemoteFileInfo faInfo);
    }
    [MessageContract]
    public class CTRemoteFileInfo : IDisposable
    {
        [MessageHeader(MustUnderstand = true)]
        public string FileName;

        [MessageHeader(MustUnderstand = true)]
        public long Length;

        [MessageBodyMember(Order = 1)]
        public System.IO.Stream FileByteStream;

        public void Dispose()
        {
            if (FileByteStream != null)
            {
                FileByteStream.Close();
                FileByteStream = null;
            }
        }
    }
    [MessageContract]
    public class CTFileName 
    {
        [MessageHeader(MustUnderstand = true)]
        public string FileName;


    }
    public class CTFileStorageClass : CTIFileStorageClass
    {

        public CTFileName UploadStream(CTRemoteFileInfo faFileInfo)
        {
            try
            {
                Guid guid = Guid.NewGuid();
                FileStream targetStream = null;
                Stream sourceStream = faFileInfo.FileByteStream;

                string uploadFolder = @"D:\Storage\";
                string[] paths=faFileInfo.FileName.Split('.');
                string path=null;
                if (paths.Length>=2)
                {
                  path="."+paths[paths.Length-1]; 
                }
                string filePath = Path.Combine(uploadFolder, guid.ToString()+path);

                using (targetStream = new FileStream(filePath, FileMode.Create,
                                      FileAccess.Write, FileShare.None))
                {
                    //read from the input stream in 65000 byte chunks

                    const int bufferLen = 65000;
                    byte[] buffer = new byte[bufferLen];
                    int count = 0;
                    while ((count = sourceStream.Read(buffer, 0, bufferLen)) > 0)
                    {
                        // save to output stream
                        targetStream.Write(buffer, 0, count);
                        Thread.Sleep(10);
                    }
                    targetStream.Close();
                    sourceStream.Close();
                }
                CTFileName fileName = new CTFileName() { FileName = guid.ToString() };
                return fileName;
            }
            catch
            {
                return null;
            }
      }
    }
}

Windows service.app.config サービスでホストされる WCF:`

<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="binding" openTimeout="04:00:00" sendTimeout="04:00:00" receiveTimeout="04:00:00" closeTimeout="04:00:00"
            allowCookies="true" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
            messageEncoding="Mtom" textEncoding="utf-8" transferMode="Streamed"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
              maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <services>
      <!-- This section is optional with the new configuration model
           introduced in .NET Framework 4. -->
      <service name="CTFileStorage.CTFileStorageClass"
               behaviorConfiguration="CalculatorServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
          </baseAddresses>
        </host>
        <!-- this endpoint is exposed at the base address provided by host: http://localhost:8000/ServiceModelSamples/service  -->
        <endpoint address=""

                  binding="basicHttpBinding" bindingConfiguration="binding" 
                  contract="CTFileStorage.CTIFileStorageClass" />
        <!-- the mex endpoint is exposed at http://localhost:8000/ServiceModelSamples/service/mex -->
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="CalculatorServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
          <serviceDebug includeExceptionDetailInFaults="False"/>
          <serviceThrottling
            maxConcurrentCalls="1000"
            maxConcurrentSessions="1000"
            maxConcurrentInstances="1000"
          />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>`

負荷をモデル化するには、クライアント コンソール アプリケーションを作成します。

    static void Main(string[] args)
    {
        Thread thread = new Thread(new ParameterizedThreadStart(Copy));
        thread.Start("D:\\toad10513\\toad10513.rar");

        Thread thread1 = new Thread(new ParameterizedThreadStart(Copy));
        thread1.Start("D:\\toad10513\\toad105131.rar");
        Thread thread2 = new Thread(new ParameterizedThreadStart(Copy));
        thread2.Start("D:\\toad10513\\toad105132.rar");
        Thread thread3 = new Thread(new ParameterizedThreadStart(Copy));
        thread3.Start("D:\\toad10513\\toad105133.rar");
        Thread thread4 = new Thread(new ParameterizedThreadStart(Copy));
        thread4.Start("D:\\toad10513\\toad105134.rar");
        Thread thread5 = new Thread(new ParameterizedThreadStart(Copy));
        thread5.Start("D:\\toad10513\\toad105135.rar");


    }
    private static void Copy(object faFile)
    {
        string s = faFile as string;
        if (s != null)
        {
            StorageClient.Storage.CTIFileStorageClassClient client = new Storage.CTIFileStorageClassClient();
            Stream sw = File.Open(s, FileMode.Open);
            Console.WriteLine(faFile.ToString());
            client.UploadStream(ref s, sw.Length, sw);

            sw.Close();
        }
    }
}
}

このアプリケーションは、ストレージにアップロードします。別のスレッドでは、ファイル サイズは 400 MB です。1 つのスレッドのアップロードを使用している場合は、正常に終了します。しかし、6 つのスレッドを開始すると、それは 3 つのスレッドしか動作せず、他のスレッドは遅れます。そして、何分かの作業の後、「接続ソケットに失敗しました」という例外が発生します。

4

0 に答える 0