我有一个背景工作者,我在里面开始一个新的背景工作者
DirectoryInfo MySubDirectory;
List<FileInfo> l;
object[] CurrentStatus;
private void _FileProcessingWorker_DoWork(object sender, DoWorkEventArgs e)
{
int countmore = 0;
try
{
DirectoryInfo[] MySubDirectories = (DirectoryInfo[])e.Argument;
for (int i = 0; i < MySubDirectories.GetLength(0); i++)
{
MySubDirectory = MySubDirectories[i];
l = new List<FileInfo>();
if (_FileCountingWorker.IsBusy == false)
_FileCountingWorker.RunWorkerAsync();
CurrentStatus = new object[6];
int totalFiles = l.Count;
CurrentStatus[3] = i.ToString();
countmore += totalFiles;
CurrentStatus[4] = countmore;
_FileProcessingWorker.ReportProgress(0, CurrentStatus);
string CurrentDirectory = "Current Directory: " + MySubDirectory.Name;
foreach (FileInfo MyFile in l)
{
CurrentStatus = new object[6];
if (_FileProcessingWorker.CancellationPending)
{
e.Cancel = true;
return;
}
if (MyFile.Extension.ToLower() == ".cs" || MyFile.Extension.ToLower() == ".vb")
{
string CurrentFile = "Current File: " + MyFile.Name;
string CurrentFileWithPath = MyFile.FullName;
CurrentStatus[0] = CurrentDirectory;
CurrentStatus[1] = CurrentFile;
_FileProcessingWorker.ReportProgress(0, CurrentStatus);
List<string> Result = SearchInFile(CurrentFileWithPath, "if");
if (Result != null && Result.Count > 0)
{
CurrentStatus[2] = Result;
_FileProcessingWorker.ReportProgress(0, CurrentStatus);
}
}
}
}
}
catch (Exception err)
{
return;
}
}
我正在检查其他后台工作人员是否忙碌如果没有启动它
if (_FileCountingWorker.IsBusy == false)
_FileCountingWorker.RunWorkerAsync();
在新的backgroundworker dowork活动中
private void _FileCountingWorker_DoWork(object sender, DoWorkEventArgs e)
{
CountFiles(MySubDirectory, l);
}
在CountFiles中
int countingFiles = 0;
private void CountFiles(DirectoryInfo di, List<FileInfo> l)
{
try
{
l.AddRange(di.EnumerateFiles());
}
catch
{
string fff = "";
}
try
{
if (di.FullName != BasePath)
{
IEnumerable<DirectoryInfo> subDirs = di.EnumerateDirectories();
if (subDirs.Count() > 0)
{
foreach (DirectoryInfo dir in subDirs)
{
CountFiles(dir, l);
countingFiles += 1;
if (countingFiles == 8382)
{
string hhhhh = "";
}
CurrentStatus[5] = countingFiles;
_FileCountingWorker.ReportProgress(0,CurrentStatus);
}
}
}
}
catch
{
string yyy = "";
}
}
然后在第二个backgroundworker progresschanged
private void _FileCountingWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (typeof(object[]) == e.UserState.GetType())
{
object[] StatusMsg = (object[])e.UserState;
if (6 == StatusMsg.GetLength(0))
{
if (StatusMsg[5] != null)
{
lblCountingFiles.Text = StatusMsg[5].ToString();
}
}
}
}
例外是在线:
lblCountingFiles.Text = StatusMsg[5].ToString();
跨线程操作无效:控制'lblCountingFiles'从其创建的线程以外的线程访问
我正在更新ProgressChanged
事件中的标签。为什么我得到例外?
我该如何解决呢?
答案 0 :(得分:2)
您正在_FileCountingWorker.RunWorkerAsync();
从另一个DoWork
主题调用BackgroundWorker
。
因此,当_FileCountingWorker
报告进度时,它不会回到UI线程,因为它不是从UI线程启动的。这就是你得到跨线程异常的原因。
尝试从UI线程或_FileCountingWorker.RunWorkerAsync()
事件中调用_FileProcessingWorker_ProgressChanged
。
否则你可以使用:
private void _FileCountingWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (!Dispatcher.CheckAccess()) // CheckAccess returns true if you're on the dispatcher thread
{
Dispatcher.Invoke(new Action<object, ProgressChangedEventArgs>(_FileCountingWorker_ProgressChanged), sender, e);
return;
}
if (typeof(object[]) == e.UserState.GetType())
{
object[] StatusMsg = (object[])e.UserState;
if (6 == StatusMsg.GetLength(0))
{
if (StatusMsg[5] != null)
{
lblCountingFiles.Text = StatusMsg[5].ToString();
}
}
}
}
答案 1 :(得分:1)
我认为问题出在你拥有的主线上
object[] CurrentStatus;
在后台,您可以在报告进度到达之前对其进行新增 (或同时)
杀死上述
只需在do_work中创建对象
object[] CurrentStatus = new object[6];