本文共 6568 字,大约阅读时间需要 21 分钟。
为了实现异步搜索C:\Program Files文件夹下包含“scyGroupBox”关键字的代码文件,我们可以使用C#中的委托和异步方法。以下是详细的实现步骤:
定义一个委托类型,指向耗时的文件搜索函数:
public delegate ListAddListViewDelegate();
编写一个函数,用于搜索文件,并返回包含指定关键字的文件列表:
public ListLoadFileByName(){ string keyword = "scyGroupBox"; string path = @"C:\Program Files\"; DirectoryInfo directory = new DirectoryInfo(path); var files = directory.GetFiles("*.cs", SearchOption.AllDirectories) .Where(p => p.Name.Contains(keyword)) .ToList(); return files;}
创建一个类,包含异步操作的逻辑:
public class AsyncFileSearch{ private readonly ListView _lsvName; private readonly List _myFiles; private readonly bool _addFlag; private readonly bool _deleteFlag; public AsyncFileSearch(ListView lsvName, List myFiles, bool addFlag, bool deleteFlag) { _lsvName = lsvName; _myFiles = myFiles; _addFlag = addFlag; _deleteFlag = deleteFlag; } public void InvokeListView() { AddListViewDelegate asyncAdd = new AddListViewDelegate(LoadFileByName); IAsyncResult iar = asyncAdd.BeginInvoke(new AsyncCallback(GetFileInfoResult), asyncAdd); AddNotification(); } private void GetFileInfoResult(IAsyncResult iar) { AddListViewDelegate asyncAdd = (AddListViewDelegate)iar.AsyncState; List list = asyncAdd.EndInvoke(iar); LoadFileIntoForm(list); } private void LoadFileIntoForm(List fileList) { _myFiles = fileList; ClearListView(); foreach (FileInfo file in fileList) { ListViewItem lvi = new ListViewItem { Text = Path.GetFileName(file.FullName), Tag = file.FullName }; AddListViewCrossThreads(lvi, _addFlag); } } private void ClearListView() { _lsvName.Items.Clear(); } private void AddNotification() { ListViewItem loadingItem = new ListViewItem { Text = "正在加载,请稍等……", Tag = 1 }; _lsvName.Items.Add(loadingItem); } private void AddListViewCrossThreads(ListViewItem lvi, int action) { if (_lsvName.InvokeRequired) { AddListViewCrossThreadDelegate del = new AddListViewCrossThreadDelegate(AddListViewCrossThreads); _lsvName.Invoke(del, lvi, action); } else { if (action == _addFlag) { _lsvName.Items.Add(lvi); } else if (action == _deleteFlag) { _lsvName.Items.Clear(); } } }} 调用AsyncFileSearch类的方法:
AsyncFileSearch asyncFileSearch = new AsyncFileSearch(lsvName, fileList, addFlag, deleteFlag);asyncFileSearch.InvokeListView();
在GetFileInfoResult方法中,处理可能的异常:
catch (Exception ex){ MessageBox.Show("搜索失败:" + ex.Message);}finally{ asyncAdd?.Invoke(null, null);} 在异步过程中,显示loading提示信息,避免用户等待:
asyncFileSearch.AddNotification();
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Threading;using System.Windows.Forms;public class AsyncFileSearch{ private readonly ListView _lsvName; private readonly List _myFiles; private readonly bool _addFlag; private readonly bool _deleteFlag; public AsyncFileSearch(ListView lsvName, List myFiles, bool addFlag, bool deleteFlag) { _lsvName = lsvName; _myFiles = myFiles; _addFlag = addFlag; _deleteFlag = deleteFlag; } public void InvokeListView() { AddListViewDelegate asyncAdd = new AddListViewDelegate(LoadFileByName); IAsyncResult iar = asyncAdd.BeginInvoke(new AsyncCallback(GetFileInfoResult), asyncAdd); AddNotification(); } private void GetFileInfoResult(IAsyncResult iar) { AddListViewDelegate asyncAdd = (AddListViewDelegate)iar.AsyncState; List list = asyncAdd.EndInvoke(iar); LoadFileIntoForm(list); } private void LoadFileIntoForm(List fileList) { _myFiles = fileList; ClearListView(); foreach (FileInfo file in fileList) { ListViewItem lvi = new ListViewItem { Text = Path.GetFileName(file.FullName), Tag = file.FullName }; AddListViewCrossThreads(lvi, _addFlag); } } private void ClearListView() { _lsvName.Items.Clear(); } private void AddNotification() { ListViewItem loadingItem = new ListViewItem { Text = "正在加载,请稍等……", Tag = 1 }; _lsvName.Items.Add(loadingItem); } private void AddListViewCrossThreads(ListViewItem lvi, int action) { if (_lsvName.InvokeRequired) { AddListViewCrossThreadDelegate del = new AddListViewCrossThreadDelegate(AddListViewCrossThreads); _lsvName.Invoke(del, lvi, action); } else { if (action == _addFlag) { _lsvName.Items.Add(lvi); } else if (action == _deleteFlag) { _lsvName.Items.Clear(); } } } private void LoadFileIntoForm(List fileList) { _myFiles = fileList; ClearListView(); foreach (FileInfo file in fileList) { ListViewItem lvi = new ListViewItem { Text = Path.GetFileName(file.FullName), Tag = file.FullName }; AddListViewCrossThreads(lvi, _addFlag); } } private void ClearListView() { _lsvName.Items.Clear(); } public List LoadFileByName() { string keyword = "scyGroupBox"; string path = @"C:\Program Files\"; DirectoryInfo directory = new DirectoryInfo(path); var files = directory.GetFiles("*.cs", SearchOption.AllDirectories) .Where(p => p.Name.Contains(keyword)) .ToList(); return files; } } // 初始化列表视图ListView lsvName = new ListView();// 初始化文件列表ListfileList = new List ();// 调用异步搜索AsyncFileSearch asyncFileSearch = new AsyncFileSearch(lsvName, fileList, true, false);asyncFileSearch.InvokeListView();
通过上述实现,用户在搜索过程中可以看到loading提示,避免了界面卡顿,同时提高了用户体验。
转载地址:http://eflvz.baihongyu.com/