【发布时间】:2015-08-11 10:05:49
【问题描述】:
如果这个问题已经得到解答,我深表歉意,我似乎无法通过 Google 获得我的答案。
我有一个使用 WCF 通信设置的服务器和客户端应用程序,并且运行良好。我的端点之一是使用 HTTP 进行流式传输(例如上传和下载文件)。我遇到的问题是当文件被上传和下载时,服务器应用程序挂起(冻结),就好像它在主线程上运行一样。这可以防止其他客户端向服务器请求。
注意:已尝试不同大小的文件都执行相同的症状。
服务器上的所有其他端点 (tcp) 没有遇到与它们运行多线程相同的症状,并且在发送和检索数据时,服务器应用程序仍然响应其他客户端。
我已经尝试了几件事 1)我已经设置了 ServiceBehaviorAttribute 一种。 InstanceContextMode = InstanceContextMode.Single 湾。 ConcurrencyMode = ConcurrencyMode.Multiple 2) 尝试设置 dispatcherSynchronization 行为以及 asynchronousSendEnabled="true" 3) 增加消息大小 maxReceivedMessageSize
请有人帮助我解决这个问题,我一直在苦苦挣扎,但找不到帮助。
服务器配置
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="FileTransferServicesBinding" transferMode="Streamed" sendTimeout="20:00:00" receiveTimeout="20:00:00" messageEncoding="Mtom" bypassProxyOnLocal="true" maxReceivedMessageSize="2147483647"></binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="MyServiceTypeBehaviors" name="DoorWay.Transfers.FileTransferService">
<endpoint behaviorConfiguration="AsyncStreaming" address="mex" binding="basicHttpBinding" bindingConfiguration="FileTransferServicesBinding" contract="DoorWay.Transfers.IFileTransferService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:1650/FileTranfer"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="AsyncStreaming">
<dispatcherSynchronization asynchronousSendEnabled="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
传输接口
[ServiceContract]
public interface IFileTransferService
{
[OperationContract]
MetaDataRecieve UploadFile(RemoteFileInfo request);
[OperationContract]
RemoteFileInfo DownloadFile(DownloadRequest request);
}
转班
[ServiceBehaviorAttribute(Name = "FileTransferService", InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class FileTransferService : IFileTransferService, IFileDownload
{
public RemoteFileInfo DownloadFile(DownloadRequest request)
{
// get some info about the input file
string filePath = System.IO.Path.Combine(Paths.ClientUpdates, request.FileName);
System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);
// check if exists
if (!fileInfo.Exists)
{
throw new Exception("File does not exist");
}
// open stream
System.IO.FileStream stream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
// return result
RemoteFileInfo result = new RemoteFileInfo();
result.FileName = request.FileName;
result.Length = fileInfo.Length;
result.FileByteStream = stream;
return result;
}
public MetaDataRecieve UploadFile(RemoteFileInfo request)
{
return new MetaDataRecieve() { FileID = this.UploadFileGeneralFile(request) };
}
private long UploadFileGeneralFile(RemoteFileInfo request)
{
FileDownloadPresenter presenter = new FileDownloadPresenter(this);
GeneralAttachmentHelper attachement = new GeneralAttachmentHelper
{
FileDataStream = request.FileByteStream,
Version = -1,
FileName = request.FileName,
FileType = request.FileType,
TableTransfer = request.TableTransfer
};
presenter.UploadFile(attachement);
return this.UploadedFileID;
}
}
客户端配置
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IFileTransferService" messageEncoding="Mtom" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:1650/FileTranfer/mex" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IFileTransferService"
contract="FileTransfer.IFileTransferService" name="BasicHttpBinding_IFileTransferService" />
</client>
</system.serviceModel>
我测试的冻结测试代码
private void DummyTransferDebugTest()
{
string file = @"C:\Data\Temp\f629c263-e0ae-4120-b002-f6091bcfa3f5\f629c263-e0ae-4120-b002-f6091bcfa3f5.rar";
using (FileStream fileRead = new FileStream(file, FileMode.Open))
{
using (MemoryStream fileStream = new MemoryStream())
{
fileStream.SetLength(fileRead.Length);
fileRead.Read(fileStream.GetBuffer(), 0, (int)fileRead.Length);
FileTransfer.FileTransferServiceClient transferPresenter = (FileTransfer.FileTransferServiceClient)this.OpenProxy(new FileTransfer.FileTransferServiceClient());
try
{
System.IO.FileInfo fileInfo = new FileInfo(file);
using (StreamWithProgress streamProgress = new StreamWithProgress(fileStream))
{
transferPresenter.UploadFile(fileInfo.Name, this.debugFile.ToString(), fileInfo.Length, FileTransfer.TransferTableEnum.RASTERS, streamProgress);
}
}
catch
{
throw;
}
finally
{
this.CloseProxy(transferPresenter);
}
}
}
}
如果还有什么我可以提供的。
谢谢一百万
【问题讨论】:
标签: c# multithreading wcf streaming wcf-binding