簡體   English   中英

使用control.begininvoke后,UI仍然沒有響應

[英]UI still non responsive after using control.begininvoke

我做了一個C#winforms應用程序。 現在我有一個有很多按鈕的表單,它調用了大量的數字運算函數,其輸出我在文本框中更新。 我調用textbox.begininvoke()方法,我將委托傳遞給更新文本框中文本的函數,但是當文本很大時,表單沒有響應,因為我無法單擊取消按鈕。 是不是有任何方式使整個表單保持響應,並且更新也不斷發生。 我必須向用戶顯示數據,因為它即將到來,我無法緩沖整個事情並最終顯示。 我還嘗試實現自己的緩沖區並以特定的時間間隔顯示數據,這對於少量文本很有用,但是大量的UI只是沒有響應。 任何幫助? 謝謝

更新問題是因為出現了一些混淆

  • 我在一個單獨的線程上調用了數字運算功能。
  • 只要數據到達以更新文本框,該數字運算函數就會調用control.begininvoke函數
  • 我的UI得到顯示,我看到輸出即將來臨,但是當數據量巨大時,我無法做任何其他活動,盡管我仍然可以看到UI

調用BeginInvoke(或Invoke)不會給你帶來任何東西,除非數字運算函數在除UI線程之外的另一個線程上運行。

請考慮以下代碼:

private void HardWork(object state)
{
    for (int i = 0; i < 10; i++)
    {
        Thread.Sleep(500);
        SetText(i.ToString());
    }
}

private void SetText(string text)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new Action<string>(SetText), text);
    }
    else
    {
        textBox1.Text = text;
    }
}
private void Button_Click(object sender, EventArgs e)
{
    ThreadPool.QueueUserWorkItem(HardWork);            
}

Button_Click方法將在單獨的線程上開始執行HardWork方法。 HardWork將進行一些處理(通過Thread.Sleep調用模擬)然后調用方法來顯示一些進度。 在這個方法中,我們需要檢查我們是否在UI線程上。 如果我們不是,我們使用Invoke (或BeginInvoke )調用相同的方法,以強制它在UI線程上執行。

更新:如果從數字運算方法發出的數據量非常大,這當然可能會對UI響應性產生負面影響。 例如,如果您在線程方法中累積了大量文本並在每次更新時發出該文本,那么這將比發布自上次更新后發生的更改更慢。 文本框也是如此; 僅使用新文本調用TextBox.AppendText將比重復分配TextBox.Text屬性更快。

由於我們沒有看到您的代碼實際上做了什么,因此很難提供有關如何解決您的特定問題的更詳細的想法。

你倒退了。

您應該使用BeginInvoke來更新UI。 它似乎不會產生一個新的線程,你似乎相信。

BeginInvoke只是“在最初創建控件的線程中執行以下操作”,這是您的UI線程。

因此,您應該在數字運算線程中使用BeginInvoke將更新回發到UI中。

希望這可以幫助

具有更新文本框的功能逐個執行並在每次更新之間調用DoEvents 也就是說,分解字符串......

update piece 1
DoEvents
update piece 2
DoEvents
...
update piece n

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM