我的問題是,只要我的程式視窗在 Dataset.fill 函式中,它就無法再移動或做出反應。
有誰知道為什么會這樣?
using (OracleCommand cmd = new OracleCommand(sqlQuery))
{
cmd.CommandType = CommandType.Text;
cmd.Connection = oraCon;
using (DataSet dSetHelper = new DataSet())
{
using (OracleDataAdapter dataAdapter = new OracleDataAdapter())
{
dataAdapter.SelectCommand = cmd;
if (!File.Exists(projPath "/" tableNameFromRow "/" tableNameFromRow ".xml"))
{
currentTableName.Text = "Export: " tableNameFromRow;
this.Refresh();
dataAdapter.Fill(dSetHelper);
dSetHelper.WriteXml(projPath "/" tableNameFromRow "/" tableNameFromRow ".xml");
}
}
}
}
uj5u.com熱心網友回復:
如果您不使用任何任務或其他多執行緒方法,Windows 表單運行一個執行緒。
可能您的查詢回應時間很長。
因此,您的主執行緒無法回應另一個行程,例如按鈕單擊或另一個事件。
對于解決方案,您可以將代碼帶到任務塊
var source = new CancellationTokenSource();
var token = source.Token;
var task = Task.Run(() => DoSomething(token), token);
你可以在這個塊中獲取你的資料。
static void DoSomething(CancellationToken token)
{
///oracle connection, get data, fill etc etc
}
uj5u.com熱心網友回復:
有誰知道為什么會這樣?
是的,簡單來說,您的程式有一個執行緒,其唯一作業是繪制 UI。它是運行任何按鈕單擊處理程式代碼等的執行緒,它不應該長時間處于忙碌狀態。當您運行 30 秒的 db 查詢時,執行緒將在等待查詢完成時停止繪制 UI,并且您所有的點擊、拖動和按鍵都將進入這個訊息佇列,等待執行緒處理它們。幾秒鐘后,Windows 可能會注意到 UI 執行緒已停止執行其保持佇列清除的正常作業(視窗 UI 訊息佇列正在建立和增加而不是清除)并且它使視窗消失并放置“無回應” "在標題中。當 db 查詢完成時,執行緒突然再次開始處理 UI 訊息,應用程式開始活躍
你不需要讓你的 UI 執行緒長時間忙碌。不要讓它執行耗時超過半秒的 IO 作業(磁盤、資料庫)。對于更長時間的作業,您可以轉換您的方法async(如果您需要更多幫助,請發布方法簽名)并執行以下操作:
await Task.Run(_ => { dataAdapter.Fill(dSetHelper); });
如果您填充大量資料,請考慮它可能具有的其他后果;也許使用讀取器從資料庫流式傳輸資料,而不是將其全部加載到資料集中。如果查詢運行緩慢,也許可以考慮優化它;將 UI 放在運行緩慢的查詢上通常會將其交到用戶手中,這意味著當他們對運行查詢按鈕感到沮喪時,他們會執行諸如錘擊運行查詢按鈕之類的事情,從而使問題復雜化..(考慮禁用該按鈕當查詢運行時)
如果要簡化代碼,則不需要using資料集,也不需要向資料配接器提供命令/連接;DA 有一個建構式,它接受一個 sql 和一個連接字串,它們為您創建命令/連接,打開它并處理它。這意味著您可以將 DA 查詢歸結為以下內容:
using var da = new...(sql,con str);
var dt = new DataTable();
da.Fill(dt);
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/335845.html
下一篇:在基類方法中使用未來的子型別別
