C# のビルドを高速化する
性能の良いSSDが手に入ったので、高速ビルドにチャレンジしてみました。
CPU:Intel Xeon E3-1280 V2 3.6GHz(8core)
Memory:32GB(DDR3)
HDD:Intel SSD 750(Read 2,200MB/s Write 900MB/s)
ソースコード規模:総ステップ 16万行、実ステップ 7万行
MSBuildのオプションは、/m:8 /t:Rebuild
結果は、17.64 Sec
アンチウイルスソフトを止めて再計測、16.04 Sec
CPU性能とSSD性能が、今後劇的に向上するのは考えにくいので、このあたりが限界かもしれませんね。昔のDelphiは、本当に速かったな。
WCF入門-11 App.config以外のファイルからサービス構成を取得する
Sample SourceWCFServer.zip
クライアント側は、app.configの場合は、clientbaseを使いますが、別のファイル(例えば、other.config)から設定を読み込む場合は使えません。
ConfigurationManager.OpenMappedExeConfigurationを使ってConfigファイルを読み込んで、ConfigurationChannelFactoryを使ってchannelを作成します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.Configuration;namespace WCFInterfaces
{
public class CustomConfigClientBase
{
private ConfigurationChannelFactory_factory = null;
private Lazy_channel = null; public string CustomConfigFileName { get; set;}
public string CustomEndpointName { get; set;}private Type CreateChannel()
{
return CreateClientChannel(ref _factory, this.CustomConfigFileName, this.CustomEndpointName);
}private T CreateClientChannel
(ref ConfigurationChannelFactory configChannelFactory,
string configFilePath, string endPointName)
{
var fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = configFilePath;
var config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
configChannelFactory = new ConfigurationChannelFactory(endPointName, config, null);
return configChannelFactory.CreateChannel();
}public CustomConfigClientBase()
{
_channel = new Lazy(CreateChannel, true);
}public Type Channel
{
get{
return _channel.Value;
}
}public void Close()
{
_factory.Close();
}
}
}
サーバー側は、app.configの場合は、servicehostを使いますが、別のファイルから読み込む場合は、ApplyConfigurationをオーバーライドする手法が使えます。
ApplyConfigurationがコンストラクタで呼び出されてしまうため、別ファイルのファイルパスはクラスのスタティック変数などで渡す必要があります。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.Configuration;namespace WCFInterfaces
{
public class CustomConfigServiceHost : ServiceHost
{public static string CustomConfigFileName {get; set;}
public CustomConfigServiceHost(Type serviceType) : base(serviceType)
{
}protected override void ApplyConfiguration()
{
var filemap = new ExeConfigurationFileMap();
filemap.ExeConfigFilename = CustomConfigServiceHost.CustomConfigFileName;var config = ConfigurationManager.OpenMappedExeConfiguration(filemap, ConfigurationUserLevel.None);
var serviceModel = ServiceModelSectionGroup.GetSectionGroup(config);bool loaded = false;
foreach (ServiceElement se in serviceModel.Services.Services) {
if (!loaded)
if (se.Name == this.Description.ConfigurationName) {
base.LoadConfigurationSection(se);
loaded = true;
}
}
if (!loaded) {
throw new ArgumentException("Service Element not found in " + CustomConfigServiceHost.CustomConfigFileName);
}
base.ApplyConfiguration();}
}
}
参照設定に、System.ServiceModelとSystem.Configurationが必要です。
C#でMethod全体を排他ロックする
javaのsynchronized相当の機能、c#では属性を指定します。
using System.Runtime.CompilerServices; [MethodImpl(MethodImplOptions.Synchronized)] public void SomeMethod() { // sync code }
プロパティのget/setにも以下のように指定できます。
public int SyncProperty { [MethodImpl(MethodImplOptions.Synchronized)] get { return i; } [MethodImpl(MethodImplOptions.Synchronized)] set { i = value; } }