잊지 않겠습니다.

System.Transaction 을 reference로 추가

System.Data쪽에 없는 것이 약간 이상하다.;


using ( TransactionScope ts = new TransactionScope() )
{
    try
    {
        Customer customer = ( from c in syncMailDB.Customers where c.ID == updateUser.CustomerPK select c ).First();

        customer.LOGONNAME = updateUser.SamAccount;
        customer.NAME = updateUser.Name;
        customer.DIAPLAYNAME = updateUser.DisplayName;
        customer.STATE = updateUser.State;
        customer.PHONEPIN = updateUser.UserPIN;
        customer.EMAIL = updateUser.EmailAddress;
        
        customer.UPDATETIME = DateTime.Now;
        syncMailDB.SubmitChanges();
        
        ts.Complete();
    }
    catch ( Exception ex )
    {
        return false;
    }
}
return true;
Posted by Y2K
,

In LDAP, Property Collection is consisted of string and ActiveDs DataTypes.

For example, if Property.Value is large integer type, this value can cast by ActiveDs.IADsLargeInteger.

this is sample code :

try
{
    string ldap = String.Format("LDAP://{0}", ldapServer);
    DirectoryEntry entry = new DirectoryEntry(ldap);
    entry.Username = SyncmailConstants.DefaultAdminId;
    entry.Password = SyncmailConstants.DefaultAdminPassword;

    DirectorySearcher seacher = new DirectorySearcher(entry, "OU=mailpushcokr");
    SearchResult searchresult = seacher.FindOne();
    DirectoryEntry ouentry = searchresult.GetDirectoryEntry();

    MembershipUserStatics statics = new MembershipUserStatics();
    foreach (DirectoryEntry entity in ouentry.Children)
    {
        if(entity.Properties.Contains("givenName"))
        {
            if (entity.Properties["givenName"].Value.ToString() == "대리점가입자")
            {
                statics.TotalUkeyUserCount++;
                if (!entity.Properties.Contains("lastLogonTimestamp"))
                {
                    statics.UnusedUkeyUserCount++;
                }
            }
            else
            {
                if (!entity.Properties.Contains("lastLogonTimestamp"))
                {
                    statics.UnuseWebUserCount++;
                }
                else
                {
                    ActiveDs.IADsLargeInteger largeIntADSI = (ActiveDs.IADsLargeInteger) entity.Properties["lastLogonTimestamp"][0];
                    Console.WriteLine(largeIntADSI.HighPart);    
                }
            }
            statics.TotalUserCount++;
        }
    }
    return statics;      
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
    return new MembershipUserStatics();   
}
Posted by Y2K
,

비동기 I/O 패턴은 고성능을 위한 최상의 선택이다.
여러개의 Multi Thread를 이용해서 최고의 성능을 가진 프로그램을 만드는 것도 역시 가능하다. [이론 상으로는..;]
잘 방어된 서버는 클라이언트가 얼마나 오랫동안 유휴상태인지 검사하여 미리 정의된 한계 이상으로 유휴상태가 계속되는 클라이언트에 대해서 연결을 끊어주어야지 된다.

IAsyncResult 를 인자로 받는 BeginAccept, BeginReceive, BeginSend는 각각 비동기 I/O에 대한 최상의 방법으로 제시된다.
각 Begin** Method에서 호출된 AsyncCallBack 함수는 그 내부에서 각각의 End** Method를 수행시켜, 그 결과를 가지고 오게 된다.

이때에, 주의할 점들은 다음과 같다.

  • private static void로 선언이 가능할 경우에 선언하라.
    • 비동기적으로 움직이는 함수의 특징상, 여러개의 instance가 만들어지기 쉽다. 이러한 상황에서 instance의 범람은 memory에 영향을 미칠 수가 있기 때문에, static으로 선언해서 이러한 낭비를 줄일 수 있다.
  • try~catch 구문을 잘 사용하라.
  • BeginAccept에서는 동기화를 위해서 ManualEvent 또는 Monitor로 socket을 잡아놓는 것이 필요하다.


private void SocketDataProcessThreadStart(object sender, DoWorkEventArgs e)
{
    Exit = false;
    socketMain = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socketMain.Bind(new IPEndPoint(IPAddress.Any, PortNumber));
    socketMain.Listen(maxPortAccept);

    while (!Exit)
    {
        try
        {
            manualEvent.Reset();
            socketMain.BeginAccept(new AsyncCallback(AcceptCallBack), socketMain);
            manualEvent.WaitOne();
        }
        catch (SocketException ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.Message);
            Console.WriteLine(ex.Message);
            ErrorEvent(ex, "SocketDataProcessThreadStart 에서 에러 발생");
            return;
        }
    }
}
Posted by Y2K
,