0

我已經在我的程序運行到一個小問題。我有一個類中有一個Socket和一些聲明的變量。拆解,處置不知道該用什麼

現在,當我離開這裏被定義的類的頁面,

Class someclass = new class; 

我希望類被「破壞」,所以,我可以用在其他相同的端口/ IP打開一個新的套接字頁。 (現在的端口和IP地址似乎與類我不解構/配置/ g.c被鎖定)

因爲我有一個C++的背景下,這是用C#我的第一次。我不知道從哪裏開始,因爲在C++中你只需調用析構函數。這將清理你的班級並刪除所有活動的套接字/變量。但我如何在c#中完成此操作。我已經閱讀了關於Idisposable課程的一些內容,但這並沒有讓事情更清楚。還有垃圾收集器和正常的解構器。我不知道該使用什麼,更重要的是如何使用它。


編輯1

正如評論如下表示:這個項目是一個Windows Phone的項目,使用一個外部庫,用於創建一個套接字並建立在Windows Phone和Beckhoff公司PLC之間的通訊。

我創建原始庫頂一個額外的層,使我更容易的變量聲明。額外的層看喜歡這樣的:

public class TwincatVar<T> : IDisposable where T : IConvertible 
{ 

    public AdsClient _AdsClient; 
    private string _PlcVar; 
    private uint _VarHandle; 
    private T _Data; 
    private DateTime _TimeStamp; 
    private bool disposed = false; 
    public EventHandler DataChanged; 

    //constructor 
    public TwincatVar(ref AdsClient AdsClient, string PlcVar) 
    { 
     //Hook up to the reference of AdsClient 
     _AdsClient = AdsClient; 

     _PlcVar = PlcVar; 

    } 

    public async Task InitFunction() 
    { 

      _VarHandle = await _AdsClient.GetSymhandleByNameAsync(_PlcVar); 

      Debug.WriteLine(_VarHandle.ToString()); 

      _Data = await _AdsClient.ReadAsync<T>(_VarHandle); 

      _AdsClient.AddNotificationAsync<T>(_VarHandle, AdsTransmissionMode.OnChange, 1000, this); 

    } 


    public T Data 
    { 

     get { return _Data; } 
     set 
     { 
      _Data = value; 
      _AdsClient.WriteAsync<T>(_VarHandle, value); 
     } 
    } 

    public DateTime TimeStamp { get { return _TimeStamp; } } 

    public void OnDataChangeEvent(T newData) 
    { 
     _TimeStamp = DateTime.Now; 
     _Data = newData; 

     //Raise the event 
     if (DataChanged != null) 
     { 
      DataChanged(this, new EventArgs()); 
     } 
    } 

}

/* 是否注意到了:IDisposable的那是因爲我已經嘗試過媒體鏈接來實現它,但是這並不能很好地工作。 */

public class TwincatDevice : IDisposable 
{ 
    public AdsClient AdsClient; 

    //Twincatdevice constructor 
    public TwincatDevice(string amsNetIdSource, string ipTarget, string amsNetIdTarget, ushort amsPortTarget = 801) 
    { 
     AdsClient = new AdsClient(amsNetIdSource, ipTarget, amsNetIdTarget, amsPortTarget); 
     AdsClient.OnNotification += DistributeEvent; 
    } 

    public static void DistributeEvent(object sender, AdsNotificationArgs e) 
    { 
     AdsNotification notification = e.Notification; 


     switch (Type.GetTypeCode((notification.TypeOfValue))) 
     { 
      case TypeCode.Boolean: ((TwincatVar<bool>)notification.UserData).OnDataChangeEvent((bool)(notification.Value)); break; 
      case TypeCode.Byte: ((TwincatVar<byte>)notification.UserData).OnDataChangeEvent((byte)(notification.Value)); break; 
      case TypeCode.Int16: ((TwincatVar<short>)notification.UserData).OnDataChangeEvent((short)(notification.Value)); break; 
      case TypeCode.Int32: ((TwincatVar<int>)notification.UserData).OnDataChangeEvent((int)(notification.Value)); break; 
      case TypeCode.Single: ((TwincatVar<float>)notification.UserData).OnDataChangeEvent((float)(notification.Value)); break; 
      case TypeCode.Double: ((TwincatVar<double>)notification.UserData).OnDataChangeEvent((double)(notification.Value)); break; 
      case TypeCode.UInt16: ((TwincatVar<ushort>)notification.UserData).OnDataChangeEvent((ushort)(notification.Value)); break; 
      case TypeCode.UInt32: ((TwincatVar<uint>)notification.UserData).OnDataChangeEvent((uint)(notification.Value)); break; 
      case TypeCode.String: ((TwincatVar<string>)notification.UserData).OnDataChangeEvent((string)(notification.Value)); break; 
     } 
    } 
} 

在下面我宣佈我「的TwinCAT變量」,我連接到dataChange事件的代碼。而且,這些連接到plc上的「.name」變量。

public class MainPageViewModel : ViewModelBase 
{ 
    public TwincatDevice client;  
    public Device _device0; 
    public Device _device1; 
    public Device _device2; 
    public Devices DeviceList = new Devices(); 
    public TwincatVar<string> Version; 

    //View Model 
    public MainPageViewModel() 
    { 
     //Create devices with initual values 
     _device0 = new Device("Device Name", "Status", "Version"); 
     _device1 = new Device("Device Name", "Status", "Version"); 
     _device2 = new Device("Device Name", "Status", "Version"); 

     //Add devices to observablecollection 
     DeviceList.Add(_device0); 
     DeviceList.Add(_device1); 
     DeviceList.Add(_device2); 

     // create the connection with the beckhoff device 
     _Create_TwincatDevice(); 
     _Create_Twincatvars(); 
    } 

    ~MainPageViewModel() 
    { 
    } 

    public void _Create_TwincatDevice() 
    { 
     // This is where the socket is openend !! 

//Create TwincatDevice 
     client = new TwincatDevice(amsNetIdSource: "192.168.11.216.1.1", 
            ipTarget: "192.168.11.126", 
            amsNetIdTarget: "192.168.11.126.1.1");   

    } 

    public async Task _Create_Twincatvars() 
    { 
     // Create Twincat Variable 
     Version = new TwincatVar<string>(ref client.AdsClient, ".Version"); 
     // Init Twincat Variable 

     await Version.InitFunction(); 
     Version.DataChanged += (o, e) => 
     { 
      Deployment.Current.Dispatcher.BeginInvoke(() => { _device0.Version = Version.Data; }); 
     }; 



     // TwincatVar<type> Name = new TwincatVar<type>(reference to TwincatDevice, "Variable name PLC"); 

    } 

} 

} 

最後但並非最不重要。在(MainPage.xaml.cs中)的「後面的頁面代碼,」我做MainViewModel的一個實例,並將其設置爲DataContext的結合。

private MainPageViewModel _MV; 
_MV = new MainPageViewModel(); 
Device_listbox.DataContext = _MV.DeviceList; 

我希望這有助於使你們能幫助我:)

+0

能否請你告訴更多的源代碼中的最佳實踐如何插座被建造。你是否使用任何指針來創建套接字並連接到它? 你可以在你的類上使用Dispose模式來處理套接字。在Dispose方法中,你可以把你的清理代碼。然後在Usage類中使用Using()塊。 – Zenwalker 2012-03-28 06:34:50

+0

@zenwalker這有點問題,因爲套接字是在外部庫中創建的,而我所做的唯一事情就是聲明一個創建套接字的類。我用的是libary可以在這裏找到: http://ads.codeplex.com/ 其用於連接PLC的使用廣告協議(在C#中的正常插座上方), – 2012-03-28 06:40:29

+0

是請不要顯示的代碼如何使用該API庫創建,連接和關閉套接字。那麼我們可以幫助你更多。 – Zenwalker 2012-03-28 06:41:57

回答

3

相比於C++ ,. NET不允許被垃圾收集程序分配的一個實例的明確破壞(類和裝箱值類型/值類型作爲通過垃圾回收器分配的類型實例的成員)。這是因爲垃圾收集器需要照顧你後清理的時候它認爲所必要的(定時間隔,內存壓力等)。如果您需要在現場釋放資源,則需要顯式調用方法。您可以將此方法命名爲Cleanup。 .NET已經有了一個很好的模式來實現這一點。方法名稱是Dispose。 (你可以實現一個Dispose方法,它具有零參數和void返回類型,或者簡單地實現IDisposable接口。將方法命名爲Dispose而不是Cleanup可以爲你提供更好的工具支持,並允許使用using語句',其中定義的範圍,其中,您的實例應被使用並且自動調用在範圍塊的末尾Dispose方法。

請參閱http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.71).aspx的詳細信息,實現Dispose方法以及如何結合析構函數使用它(和固有的垃圾收集器)

+0

除了調用Dispose方法之外,還應該實現'IDisposable'。如果你的類是可繼承的,通常的做法是實現'IDisposable.Dispose(void)'調用一個受保護的'Dispose(bool)'函數來完成實際的處理。 – supercat 2012-03-28 16:20:09