c# - 尝试触发事件时出现 NullReferenceException

标签 c# multithreading events

我正在学习如何创建事件和创建多线程应用程序。

方法 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/

相关文章:

javascript - javascript 中的 C# 只执行一次

c++ - 在不同线程中取消引用指向原子对象的只读非原子指针是否安全?

c++ - 为什么 GET_X_LPARAM 确实返回鼠标滚轮上的绝对位置?

java - PaintComponent显示不清楚

javascript - 是否可以在常规对象(不是 DOM 对象)上分派(dispatch)事件?

c# - WPF 组合框所选项目

c# - 在派生的 C# 用户控件中处理 Windows 通知

Swift for iOS - 2 个 for 循环同时运行?

c++ - 将 vector 元素的引用传递给线程函数

c# - 使用.NET Framework 4.8 WinForm webView控件显示本地html