簡體   English   中英

C#應用程序不是交互式的,而循環在后面運行

[英]C# Application is not intertactive while a loop runs in back

我已經在c#vs 2010 .net 4.0中進行了應用。 它從gmail獲取rss feed,然后在一個簡單的表格中顯示它們。 但是,當我使用計時器從40秒的時間檢查字符串rss中的更新時,問題就開始了。 該程序工作正常,但變得無響應,我無法單擊按鈕或任何東西。 我需要幫助。 注意任務開始后,我的應用程序必須可運行。

是。 您的應用程序正在UI線程上完成其工作,而沒有與Windows事件循環進行交互。 您需要在后台線程上進行工作(也許使用BackgroundWorker )。

這是一個在WinForms應用程序中使用BackgroundWorker的非常簡單的示例(但請檢查上面鏈接的類文檔):

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        var bw = new BackgroundWorker();
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        bw.RunWorkerAsync();
    }

    // update UI back on main thread
    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        listBox1.Items.AddRange(content.ToArray());
    }

    List<string> content;

    // do work on background thread
    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        content = new List<string>();
        // simulate slow update
        for (int i = 0; i < 1000; i++)
        {
            Thread.Sleep(10);
            content.Add(i.ToString());
        }
    }
}

我會研究異步方法來下載,例如WebClient.DownloadStringAsync

后台工作者或異步Web客戶端是必經之路。 我只想補充一點,我上次使用Web客戶端時發現了奇怪的行為。 我從webclient對象發出的每個首次調用將導致大約30-40秒的等待,直到檢索到數據為止。 隨后的通話會更快。 最終與webclients默認代理設置有關,將代理設置為null可以消除等待。

將代理設置為null可能不是最好的解決方案,只是提及它以防您導致更好的解決方案。

請勿為此使用后台線程。 異步!=新線程。 如果您使用新線程來執行同步Web請求,您將(很快)使線程池餓死(假設您正在使用后台工作程序)。

一個線程可以管理數百個異步Web請求,但一次只能管理一個同步請求。

如果您是初學者,我強烈建議您遵循CodeInChaos的建議並使用WebClient。 WebClient的好處是可以為您處理所有異步管道。 缺點是因為它會為您做所有事情,所以您對webrequest失去了很多控制權(例如,無法修改http標頭等),並且它還會在UI線程上返回結果(在您的情況下,這實際上是一件好事) )。

var webUri = new Uri("www.website.com");
var webClient = new WebClient();

webClient.DownloadDataCompleted += DownloadDataCallback;
webClient.DownloadStringAsync(webUri, null);

private void DownloadDataCallback (Object sender, DownloadDataCompletedEventArgs e)
{
     var webRequestResult = e.Result;
}

在循環內,在任何地方寫以下行

Application.DoEvents()

暫無
暫無

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

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