-2
我正在開發一個應用程序,它將主動從文件中讀取並實時分析和顯示該文件中的信息到UI。如何使用線程實時更新UI
我讀過的一切都告訴我我應該使用某種線程來做到這一點。我已經探索過後臺工作人員,並嘗試在運行時創建一個單獨的線程,並使用該線程更新所有UI元素。
當我不能(或不應該)進行交叉線程調用時,問題就出現了,因爲原始UI元素是在不同的線程上創建的。
有沒有辦法在線程上創建這些UI元素來更新它們?做這個的最好方式是什麼?
編輯:有一個回覆這篇文章(現在已經消失)解釋我應該如何做到這一點。在使用描述的方法更新我的代碼之後 這是我用過的更新過的代碼。一切都很好,直到我加入文件系統觀察者。只要我補充一點,我得到了關於不進行交叉線程調用的相同錯誤。
會議是I類通過創建日誌文件
private Session s1 = new Session("");
private FileSystemWatcher fsw;
private OpenFileDialog ofd1 = new OpenFileDialog();
private BackgroundWorker bgw;
private bool logActive = false;
public frmMain()
{
InitializeComponent();
bgw = new BackgroundWorker();
bgw.WorkerReportsProgress = true;
bgw.ProgressChanged += HandleProgressChanged;
bgw.DoWork += HandleDoWork;
fsw = new FileSystemWatcher(@"H:\Logs", "*.txt");
fsw.SynchronizingObject = this;
fsw.IncludeSubdirectories = false;
fsw.EnableRaisingEvents = true;
fsw.NotifyFilter = NotifyFilters.Size;
fsw.Changed += new FileSystemEventHandler(fsw_OnChanged);
}
private void frmMain_Load(object sender, EventArgs e)
{
ofd1.Filter = "log files (*.txt)|*.txt|All files (*.*)|*.*";
ofd1.FilterIndex = 2;
ofd1.RestoreDirectory = true;
}
private void fsw_OnChanged(object source, System.IO.FileSystemEventArgs e)
{
bgw.RunWorkerAsync();
}
// this runs on the UI thread
// here's where you update the UI based on the information from the event args
private void HandleProgressChanged(object sender, ProgressChangedEventArgs e)
{
for (int i = s1.previousLineNumber; i < s1.GetMessageCount(); i++)
{
ListViewItem lvi = new ListViewItem((s1.GetMessage(i).date).ToString());
lvi.SubItems.Add(s1.GetMessage(i).type.ToString());
lvi.SubItems.Add(s1.GetMessage(i).data);
listView1.Items.Add(lvi);
}
}
// this runs on a background thread; you cannot modify UI controls here
private void HandleDoWork(object sender, DoWorkEventArgs e)
{
s1.ParseLiveFile();
bgw.ReportProgress(100);
}
最好的方法是使用委託來訪問主線程conrols。這很容易,並在stackoverflow上多次描述。搜索一下,我相信你會找到有用的答案。 – 2013-03-03 21:13:30
您的方法存在一個基本缺陷:您可以從其他線程操縱UI,並在「前臺」線程中執行實際的工作/邏輯(例如數據分析)。但是,大多數UI框架只需要相反的內容:在後臺線程中執行該工作,並從單個前臺線程(「UI線程」)更新UI。 – stakx 2013-03-03 21:16:44
不幸的是,這已經超出了我的直接知識領域,但我可以告訴你解決方案的大致方向:使用衆多線程池庫中的一個爲每次文件系統更改啓動任務。這些線程將根據文件信息構建數據結構,然後通過延續將數據返回到UI線程,然後UI線程可以填充控件。 – siride 2013-03-04 00:01:33