共用方式為


遠端處理範例:存留期

本主題專門說明一項為了在現有應用程式中提供回溯相容性而保留的舊有技術,不建議用於新的開發工作。分散式應用程式應使用 Windows Communication Foundation (WCF) 進行開發。

下列程式碼範例示範幾種存留期租用期案例。Client.exe 會註冊贊助者 (在一開始的租用期間過後) 並更新 TimeSpan 的租用期 (與 ClientActivatedType.InitializeLifetimeService() 中指定的租用期不同)。請注意,由於 MyClientSponsor 會延伸 MarshalByRefObject,因此可以傳址方式傳遞給租用管理員 (在 Server.exe 應用程式定義域中)。這個應用程式會在單一電腦或網路上執行。如果您要透過網路執行這個應用程式,您必須以遠端電腦的名稱取代用戶端組態中的 "localhost"

6tkeax11.Caution(zh-tw,VS.100).gif注意:
.NET 遠端處理依預設不執行驗證或加密。因此,建議您採取所有必要的步驟,以驗證用戶端或伺服器的識別,然後再與其進行遠端互動。由於 .NET 遠端處理應用程式需要 FullTrust 權限才能執行,所以如果某個未經授權的用戶端被授與伺服器的存取權,該用戶端就可以執行程式碼,如同它已完全受信任。請務必驗證您的端點並加密通訊資料流,方法包括在網際網路資訊服務 (IIS) 中裝載遠端型別或建置自訂通道接收組來進行這項工作。

請依序執行 Server.exe 與 Client.exe,接著您就會看到如下列的輸出:

Server.exe:

C:\projects\Lifetime\Server\bin>server

The server is listening. Press Enter to exit....

ClientActivatedType.RemoteMethod called.

Client.exe:

C:\projects\Lifetime\Client\bin>client

Client-activated object: RemoteMethod called. MyDomain\SomeUser

Press Enter to end the client application domain.

I've been asked to renew the lease.

Time since last renewal:00:00:09.9432506

I've been asked to renew the lease.

Time since last renewal:00:00:29.9237760

若要編譯這個範例

  1. 在命令提示字元上輸入下列命令:

    csc /t:library RemoteType.cs
    csc /r:System.Runtime.Remoting.dll /r:RemoteType.dll server.cs
    csc /r:System.Runtime.Remoting.dll /r:RemoteType.dll client.cs
    
    vbc /t:library RemoteType.vb
    vbc /r:System.Runtime.Remoting.dll /r:RemoteType.dll server.vb
    vbc /r:System.Runtime.Remoting.dll /r:RemoteType.dll client.vb
    

RemoteType

using System;
using System.Runtime.Remoting.Lifetime;
using System.Security.Principal;

namespace RemoteType
{
    public class ClientActivatedType : MarshalByRefObject
    {
        public override Object InitializeLifetimeService()
        {
            ILease lease = (ILease)base.InitializeLifetimeService();

            // Normally, the initial lease time would be much longer.
            // It is shortened here for demonstration purposes.
            if (lease.CurrentState == LeaseState.Initial)
            {
                lease.InitialLeaseTime = TimeSpan.FromSeconds(3);
                lease.SponsorshipTimeout = TimeSpan.FromSeconds(10);
                lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
            }
            return lease;
        }

        public string RemoteMethod()
        {
            // Announces to the server that the method has been called.
            Console.WriteLine("ClientActivatedType.RemoteMethod called.");

            // Reports the client identity name.
            return "RemoteMethod called. " + WindowsIdentity.GetCurrent().Name;
        }
    }
}
Imports System
Imports System.Runtime.Remoting.Lifetime
Imports System.Security.Principal

Namespace RemoteType
Public Class ClientActivatedType
    Inherits MarshalByRefObject

    Public Overrides Function InitializeLifetimeService() As Object
        Dim lease As ILease = MyBase.InitializeLifetimeService()

        ' Normally, the initial lease time would be much longer.
        ' It is shortened here for demonstration purposes.
        If (lease.CurrentState = LeaseState.Initial) Then
            lease.InitialLeaseTime = TimeSpan.FromSeconds(3)
            lease.SponsorshipTimeout = TimeSpan.FromSeconds(10)
            lease.RenewOnCallTime = TimeSpan.FromSeconds(2)
        End If
        Return lease
    End Function

    Public Function RemoteMethod() As String
        Console.WriteLine("ClientActivatedType.RemoteMethod called.")

        ' Reports the client identity name.
        Return "RemoteMethod called. " & WindowsIdentity.GetCurrent().Name
    End Function

End Class
End Namespace

伺服器

using System;
using System.Runtime.Remoting;

namespace Server
{
    class Program
    {
        static void Main(string[] args)
        {
            RemotingConfiguration.Configure("Server.exe.config", false);
            Console.WriteLine("The server is listening. Press Enter to exit....");
            Console.ReadLine();
        }
    }
}
Imports System
Imports System.Runtime.Remoting

Class Program
    Shared Sub Main()
        RemotingConfiguration.Configure("Server.exe.config", False)
        Console.WriteLine("The server is listening. Press Enter to exit....")
        Console.ReadLine()
    End Sub
End Class

Server.exe.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.runtime.remoting>
    <application>
      <channels>
        <channel ref="tcp" port="1234">
          <serverProviders>
            <formatter ref="binary" typeFilterLevel="Full"/>
          </serverProviders>
          <clientProviders>
            <formatter ref="binary"/>
          </clientProviders>
        </channel>
      </channels>
      <service>
        <activated type="RemoteType.ClientActivatedType, RemoteType" />
      </service>
    </application>
  </system.runtime.remoting>
</configuration>

用戶端

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Lifetime;
using RemoteType;

class Client
{
    static void Main(string[] args)
    {
        RemotingConfiguration.Configure("Client.exe.config",false);
        ClientActivatedType obj = new ClientActivatedType();

        ILease lease = (ILease)obj.GetLifetimeService();
        MyClientSponsor sponsor = new MyClientSponsor();
        lease.Register(sponsor);

        Console.WriteLine("Client-activated object: " + obj.RemoteMethod());
        Console.WriteLine("Press Enter to end the client application domain.");
        Console.ReadLine();
    }
}

public class MyClientSponsor : MarshalByRefObject, ISponsor
{
    private DateTime lastRenewal;

    public MyClientSponsor()
    {
        Console.WriteLine("MyClientSponsor.ctor called");
        lastRenewal = DateTime.Now;
    }

    public TimeSpan Renewal(ILease lease)
    {
        Console.WriteLine("I've been asked to renew the lease.");
        Console.WriteLine("Time since last renewal:" + (DateTime.Now - lastRenewal).ToString());

        lastRenewal = DateTime.Now;
        return TimeSpan.FromSeconds(20);
    }
}
Imports System
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Lifetime
Imports RemoteType

Class Client

    Shared Sub Main()
        RemotingConfiguration.Configure("Client.exe.config", False)
        Dim obj As ClientActivatedType = New ClientActivatedType()

        Dim lease As ILease = CType(obj.GetLifetimeService(), ILease)
        Dim sponsor As MyClientSponsor = New MyClientSponsor()
        lease.Register(sponsor)

        Console.WriteLine("Client-activated object: " + obj.RemoteMethod())
        Console.WriteLine("Press Enter to end the client application domain.")
        Console.ReadLine()
    End Sub

End Class

Public Class MyClientSponsor
    Inherits MarshalByRefObject
    Implements ISponsor

    Dim lastRenewal As DateTime

    Public Sub New()
        lastRenewal = DateTime.Now
    End Sub

    Public Function Renewal(ByVal lease As System.Runtime.Remoting.Lifetime.ILease) As System.TimeSpan Implements System.Runtime.Remoting.Lifetime.ISponsor.Renewal
        Console.WriteLine("I've been asked to renew the lease.")
        Console.WriteLine("Time since last renewal:" + (DateTime.Now - lastRenewal).ToString())

        lastRenewal = DateTime.Now
        Return TimeSpan.FromSeconds(20)
    End Function
End Class

Client.exe.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.runtime.remoting>
    <application>
      <channels>
        <channel ref="tcp" port="0">
          <clientProviders>
            <formatter ref="binary"/>
          </clientProviders>
          <serverProviders>
            <formatter ref="binary" typeFilterLevel="Full"/>
          </serverProviders>
        </channel>
      </channels>
      <client url="tcp://localhost:1234">
        <activated type="RemoteType.ClientActivatedType, RemoteType" />
      </client>
    </application>
  </system.runtime.remoting>
</configuration>

另請參閱

其他資源

遠端處理範例
物件啟動與存留期