単純な 32 ビット テスト プロジェクトを作成しました。カウンター関数のみです。クライアントは、常に関数を呼び出すためにいくつかのスレッドを作成します。実行に 30 スレッドを使用し、3 分後 (または最大 20000 カウント)、サーバー メモリが断片化されました (ダンプ ファイルを作成し、WinDbg を使用してそれを開き、!address -summary を入力して、使用法による空き最大領域が 64kb であることを確認できます) 、クライアントのデバッグを直接停止すると、サーバーが OutOfMemoryException をスローする場合があります。何が起こったのか、この問題を解決する方法を教えてください。ありがとう。
サーバーコード:
using System;
using System.ServiceModel;
namespace Server
{
class Program
{
static void Main(string[] args)
{
var tcpAddress = new Uri("net.tcp://localhost:9998/wcf");
using (var host = new ServiceHost(typeof(DataProvider), tcpAddress))
{
host.AddServiceEndpoint(typeof (IData), new NetTcpBinding(), "");
host.Opened += delegate { Console.WriteLine("Service is running..."); };
host.Open();
Console.ReadLine();
host.Close();
}
}
}
[ServiceContract(Namespace = "WCF.Demo")]
public interface IData
{
[OperationContract]
string GetCounter();
}
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.PerSession)]
public class DataProvider : IData
{
public int Counter { get; set; }
public string GetCounter()
{
return string.Format(" counter = {0} test test test test test test test test test test test test test test",
++Counter);
//return ++Counter;
}
}
}
クライアントコード
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Threading;
namespace Client
{
class Program
{
private static readonly CancellationTokenSource Cts = new CancellationTokenSource();
static void Main(string[] args)
{
Console.WriteLine("Thread count:");
var threadCount = int.Parse(Console.ReadLine());
var cf = new ChannelFactory<IData>(new NetTcpBinding(),
new EndpointAddress("net.tcp://localhost:9998/wcf"));
for (var i = 0; i < threadCount; i++)
{
new Thread(() =>
{
var name = Thread.CurrentThread.Name;
var proxy = cf.CreateChannel();
while (!Cts.Token.IsCancellationRequested)
{
Thread.Sleep(10);
Console.WriteLine("{2}: {0}\t{1}", name, proxy.GetCounter(),
DateTime.Now.ToString("HH:mm:ss.fff"));
}
((IChannel)proxy).Close();
}) { Name = "thread " + i, IsBackground = true }.Start();
}
Console.Read();
//Cts.Cancel();
Thread.Sleep(100);
}
}
[ServiceContract(Namespace = "WCF.Demo")]
public interface IData
{
[OperationContract]
string GetCounter();
}
}