Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NullReferenceException when attempting to fire an event

I'm learning about creating events and creating multi-threaded applications.

The method Thread is called by another class which populates the params with search conditions. A BackgroundWorker is created, performs a search and returns the results to worker_RunWorkerCompleted.

Within worker_RunWorkerCompleted, I want to send the results back to my UI which is subscribing to the Fireendofsearch event.

I'm having trouble understanding why my code below throws the following error

Object reference not set to an instance of an object.

when I fire the event 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);
        }
    }
}
like image 401
Damo Avatar asked Aug 07 '26 01:08

Damo


1 Answers

Firendofsearch will be null until someone subscribes to it, change your work completed event handler to this to fix it.

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Result != null)
    {
        var friendOfSearch = Fireendofsearch;
        if(friendOfSearch != null)
           friendOfSearch (e.Result, a);
    }
}

The reason I copy it to a variable is if someone in another thread is the last person to unsubscribe between the null check and the raising of the event you will still get the null reference exception, by coping to another variable first it solves that problem.


However I would make some other changes if I where writing it, you are retuning a null EventArgs for some reason and passing the result back as the "Sender" in the traditional event pattern. I would change your code to this

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;}
}

This was all written in the SO text box so there may be one or two errors.

like image 61
Scott Chamberlain Avatar answered Aug 09 '26 13:08

Scott Chamberlain