我正在学习如何创建事件和创建多线程应用程序。
方法 Thread
被另一个类调用,该类用搜索条件填充参数。创建一个 BackgroundWorker
,执行搜索并将结果返回给 worker_RunWorkerCompleted
。
在 worker_RunWorkerCompleted
中,我想将结果发送回我订阅 Fireendofsearch
事件的 UI。
我无法理解为什么我的下面的代码会抛出以下错误
Object reference not set to an instance of an object.
当我触发事件 Fireendofsearch
public class BackgroundSearch
{
public event SearchResultCompleteThreaded Fireendofsearch;
public EventArgs a = null;
public delegate void SearchResultCompleteThreaded(object seachresults, EventArgs a);
internal void Thread(string folder, string parms)
{
var Argument = new List<object> { folder, parms };
var worker = new BackgroundWorker {WorkerReportsProgress = false, WorkerSupportsCancellation = false};
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync(Argument);
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
var passedAugue = e.Argument as List<object>;
var returnResult = new List<string[]>();
if (passedAugue != null)
{
var result = Directory.GetFiles(passedAugue[0].ToString(), passedAugue[1].ToString(), SearchOption.AllDirectories);
foreach (string s in result)
{
var t = new string[4];
t[0] = s;
t[1] = File.GetCreationTime(s).ToString();
t[2] = File.GetLastAccessTime(s).ToString();
t[3] = File.GetLastWriteTime(s).ToString();
returnResult.Add(t);
}
}
if (returnResult.Count != 0)
{
e.Result = returnResult;
}
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Result != null)
{
Fireendofsearch(e.Result, a);
}
}
}
最佳答案
在有人订阅之前,Fireendofsearch 将为空,将您的工作完成事件处理程序更改为此以修复它。
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Result != null)
{
var friendOfSearch = Fireendofsearch;
if(friendOfSearch != null)
friendOfSearch (e.Result, a);
}
}
我将它复制到一个变量的原因是,如果另一个线程中的某个人是最后一个在空检查和事件引发之间取消订阅的人,你仍然会得到空引用异常,通过首先应对另一个变量来解决那个问题。
但是,如果我在编写它的地方进行一些其他更改,您出于某种原因正在重新调整空 EventArgs
并将结果作为传统事件模式中的“发件人”传回。我会把你的代码改成这个
public event EventHandler<FriendOfSearchArgs> FirendsOfSearch;
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Result != null)
{
RaiseFriendOfSearch(e.Result);
}
}
protected virtual void RaiseFriendOfSearch(object result)
{
var friendOfSearch = FirendsOfSearch;
if(friendOfSearch != null)
friendOfSearch(this, new FriendOfSearchArgs(result));
}
public class FriendOfSearchArgs : EventArgs
{
public FriendOfSearchArgs(object result)
{
Result = result;
}
public object Result {get; private set;}
}
这都是在 SO 文本框中写的,所以可能会有一两个错误。
关于c# - 尝试触发事件时出现 NullReferenceException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13221115/