Analytics

顯示具有 WinForm 標籤的文章。 顯示所有文章
顯示具有 WinForm 標籤的文章。 顯示所有文章

2011年12月15日 星期四

[WinForm]使用 GC.Collect解決Form與Form之前的傳遞 造成記憶體無法回收(Use GC.Collect resolve transfer From the Form before causing memory can not be recovered)


問題

Form與Form之前的傳遞 造成記憶體無法回收
當有類似A Form呼叫B Form ,使用者須於B處理資料以後,更新回A的需求時,通常會在B的程式裡加上A的屬性,如下:
A Form 畫面
1
2
B Form 畫面
3
4
寫法如下:
B Form定義A Form的屬性,將A Form傳回
public GCTestMain MainForm
{
    get;
    set;
}

因此當B更新資料以後,要傳回給A時,直接呼叫A進行資料更新,並關閉如下:
MainForm.dataGridView1.DataSource = null;
MainForm.dataGridView1.Refresh();

MainForm.dataGridView1.DataSource = this.dataGridView1.DataSource;
MainForm.dataGridView1.Refresh();
this.Close();
但記憶體卻始終沒回收!!
5




解決方法

在B Form呼叫A Form 更新資料以後,強制GC回收,如下:
MainForm.dataGridView1.DataSource = null;
MainForm.dataGridView1.Refresh();
GC.Collect();
GC.WaitForPendingFinalizers();

MainForm.dataGridView1.DataSource = this.dataGridView1.DataSource;
MainForm.dataGridView1.Refresh();
this.Close();
很快的就會看到效果(測試程式裡的GRID有66萬筆資料,所以記憶體佔3百多MB是正常的):
6

2011年1月6日 星期四

[WinForm]使用 Controls.Find 取得/給予控制項資料(Use Controls.Find get / give information controls)


問題
使用 Controls.Find 取得/給予控制項資料



解決方法
給予值
private void AssignValue(string controlName,string val)
{
 Control[] ctl = this.Controls.Find(controlName, true);
 //這邊是示範TextBox
 ((TextBox)ctl[0]).Text = val;
}
取得值
private string GetValue(string controlName)
{
 Control[] ctl = this.Controls.Find(controlName, true);
 //這邊是示範TextBox
 return ((TextBox)ctl[0]).Text;
}

2010年5月15日 星期六

[Crystal Reports]解決 嘗試載入 Crystal Reports 執行階段時發生錯誤。可能是 Crystal Reports 登錄機碼權限不足,或是 Crystal Reports 執行階段安裝不正確。請安裝適當的 Crystal Reports 可轉散佈程式 (CRRedist*.msi),其中包含所需的正確 Crystal Reports 執行階段版本 (x86、x64 或 Itanium)。如需詳細資訊,請至 http://www.businessobjects.com/support。 問題


問題

嘗試載入 Crystal Reports 執行階段時發生錯誤。可能是 Crystal Reports 登錄機碼權限不足,或是 Crystal Reports 執行階段安裝不正確。請安裝適當的 Crystal Reports 可轉散佈程式 (CRRedist*.msi),其中包含所需的正確 Crystal Reports 執行階段版本 (x86、x64 或 Itanium)。如需詳細資訊,請至 http://www.businessobjects.com/support。

最近在開發Winform使用Access資料庫存取資料時,發現幾個問題!!
終於,最後找了好久,也試了好多方法,問題終於被我解出來了!
如果有這樣的問題的話,不訪參考看看 .

解決方法

背景:
Winform是以Visual Studio 2008開發,環境是windows xp sp3,資料庫以Access作為存取,Access的附檔名是.mdf,以Crystal Report作為報表工具

問題發生經過:
當在windows xp底下執行程式時,資料庫可以存取,報表也可以如期的執行,但當移到x64的作業系統上,資料庫變得不能存取,想當然爾,Crystal Report也不能執行,真是莫名其妙,上了google查一下有沒有解答.

狀況1
上了google查到Access資料庫不能存取的原因結果答案是Microsoft.Jet.OLEDB.4.0的Provider不支援x64平台的運行,一但要用Microsoft.Jet.OLEDB.4.0的話,在建置應用程式的時候,要把AnyCPU改成x86,這樣一來的話Access資料庫就可以如期執行.

狀況2
好玩的來了,在x64的平台上,開發的程式在Access資料庫的資料都可以查詢了,但在列印報表的時候,出現以下錯誤
嘗試載入 Crystal Reports 執行階段時發生錯誤。可能是 Crystal Reports 登錄機碼權限不足,或是 Crystal Reports 執行階段安裝不正確。請安裝適當的 Crystal Reports 可轉散佈程式 (CRRedist*.msi),其中包含所需的正確 Crystal Reports 執行階段版本 (x86、x64 或 Itanium)。如需詳細資訊,請至 http://www.businessobjects.com/support。
挖哩....好吧!所以去http://www.businessobjects.com/support找到CRRedistx64.msi安裝,想說在x64的系統裡,也許要用x64的版本...

要安裝時....出現已安裝???奇怪了,想說既然裝好了怎麼會錯誤哩~
所以...我在去一次http://www.businessobjects.com/support,不過這次是去下載 CRRedist.msi..

= =結果不行安裝,這...搞甚麼鬼....SAP(Crystal Reports公司)在搞人嗎?

結果以錯誤訊息去google找...也都只有一個答案"把AnyCPU改成x86",可是我已經改了阿!悶~

突然一個想法閃過...那試試看把Access資料庫改成支援x64系統的版本好了,於是用Access 2007把原來的資料庫匯入,把db換成Access 2007版本(附檔名為.accdb)

結果程式在連資料庫的時候,出現"無法辨識資料庫"

.....搞甚麼鬼?? 一樣,在去google一下 !發現Access 2007的連線字串跟之前的不一樣 之前像這樣
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;Jet OLEDB:Database Password=MyDbPassword;
之後改成這樣
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\mydatabase.accdb;Jet OLEDB:Database Password=MyDbPassword;
原來Provider改掉啦!難怪,改掉後再試一次....結果來是一樣"無法辨識資料庫",不死心,一定有哪裡有問題!!

在去google,哈哈~之後找到原來要安裝AccessDatabaseEngine才有辦法辨識(注意歐,2007跟2010的engine不一樣) 好啦!再試試看有沒有問題 ...Access 2007的資料庫連的上,程式也可以查的到資料 ...Crystal Reports也正常了!ya!終於~

最後的心得與整理
1.在x86所建置的程式access(.mdf)可以正常執行, Crystal Reports也可以正常執行
2.在x64平台裡,由於不支援舊的 Provider所以要使用新的Provider(也就是DB要用2007以上的.accdb的資料庫),或是以指定平台x86方式建置程式
3.另外Crystal Reports會因為在x64的系統裡,所以安裝時會選擇x64的版本
,但是如果程式使用x86的方式建置,db使用 access(.mdf)的話,會造成Crystal Reports x64無法叫用,因為建置時指定x86,那應該要用x86的Crystal Reports版本
4.若建置程式使用AnyCPU的話(不指定平台),則DB使用access 2007以上版本,報表及可正常運行,但若在沒安裝access 2007以上版本的x86平台運行時,則要安裝對應的
AccessDatabaseEngine
以上
~ PS.最近發現這篇文章很多人看,可見不少人遇到這樣的問題,希望有幫上忙! -2011.01.04

2010年5月12日 星期三

[C#]使用 System.Management取得IP資訊(Using System.Management get IP information)


問題
使用 System.Management取得IP資訊



解決方法
using System.Management;

public void GetIPNotUsingSystemNety()
{
    ManagementObjectSearcher query = 
        new ManagementObjectSearcher(@"SELECT * 
                                    FROM Win32_NetworkAdapterConfiguration 
                                    WHERE IPEnabled = 'TRUE'");
    ManagementObjectCollection queryCollection = query.Get();
    string ans = "\r\n";
    foreach (ManagementObject mo in queryCollection)
    {
        string[] addresses = (string[])mo["IPAddress"];
        string[] subnets = (string[])mo["IPSubnet"];
        string[] defaultgateways = (string[])mo["DefaultIPGateway"];
        ans += "Network Card: " + mo["Description"] + "\r\n";
        for (int i = 0; i<=addresses.GetLength(0); i++)
        {
            try{
                ans += " IP Address: " + addresses[i].ToString() + "\r\n";
            }
            catch (Exception ex){
                ans += " IP Address: " + "\r\n";
            }
            try{
                ans += " Subnet Mask: " + subnets[i].ToString() + "\r\n";
            }
            catch (Exception ex){
                ans += " Subnet Mask: " + "\r\n";
            }
            try{
                ans += " Gateway: " + defaultgateways[i].ToString() + "\r\n";
            }
            catch (Exception ex){
                ans += " Gateway: " + "\r\n";
            }
        }
        ans += " MAC Address: " 
            + mo["MACAddress"] + "\r\n";
        ans += " DNS Address: " + mo["DNSHostName"] + "\r\n";
        /*
        ans += " DNS Address: " + Dns.GetHostAddresses(mo["DNSHostName"].ToString())[0].ToString() 
            + "\r\n";ans += " DHCP DHCPEnabled : " + mo["DHCPEnabled"] + "\r\n";
        */
        ans += " DHCP Server Address: " + mo["DHCPServer"] + "\r\n";
    }
}

熱門文章