Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IsNumberMatch in a Parallel.ForEach loop generates System.NullReferenceException in RegexInterpreter.Go() #84

Closed
nbsoftware opened this issue Oct 31, 2018 · 6 comments

Comments

@nbsoftware
Copy link

Hi,

I am having thread safety issues with IsNumberMatch.
At least on Xamarin.iOS - haven't test yet on plain .NET.

The following (excerpt) code (running on Xamarin.iOS) :

var phoneNumberUtil = PhoneNumberUtil.GetInstance();

SynchronizedCollection<Contact> contactList = new SynchronizedCollection<Contact>();

// Assume AddressBook is a List<T> (where T is a Contact object)
// already filled with the user's address book:
Parallel.ForEach(AddressBook, c =>
    {
        if (c.Numbers == null || c.Numbers.Count == 0)
            return;
        foreach (var n in c.Numbers)
        {
            var m = phoneNumberUtil.IsNumberMatch(phoneNumber, n);
            if (m == PhoneNumberUtil.MatchType.NOT_A_NUMBER
                || m == PhoneNumberUtil.MatchType.NO_MATCH)
                continue;
            else
                contactList.Add(c);
        }
    }
);

generates the following exception:

System.NullReferenceException: Object reference not set to an instance of an object

with the following stack trace:

RegexInterpreter.Go ()
RegexRunner.Scan (System.Text.RegularExpressions.Regex regex, System.String text, System.Int32 textbeg, System.Int32 textend, System.Int32 textstart, System.Int32 prevlen, System.Boolean quick, System.TimeSpan timeout)
Regex.Run (System.Boolean quick, System.Int32 prevlen, System.String input, System.Int32 beginning, System.Int32 length, System.Int32 startat)
Regex.Match (System.String input)
PhoneNumberUtil.ExtractPossibleNumber (System.String number)
PhoneNumberUtil.BuildNationalNumberForParsing (System.String numberToParse, System.Text.StringBuilder nationalNumber)
PhoneNumberUtil.ParseHelper (System.String numberToParse, System.String defaultRegion, System.Boolean keepRawInput, System.Boolean checkRegion, PhoneNumbers.PhoneNumber+Builder phoneNumber)
PhoneNumberUtil.Parse (System.String numberToParse, System.String defaultRegion, PhoneNumbers.PhoneNumber+Builder phoneNumber)
PhoneNumberUtil.Parse (System.String numberToParse, System.String defaultRegion)
PhoneNumberUtil.IsNumberMatch (System.String firstNumber, System.String secondNumber)
ContactServiceImplementation+<>c__DisplayClass3_0.<FindContactsByPhoneNumber>b__0 (Plugin.ContactService.Shared.Contact c)
Parallel+<>c__DisplayClass31_0`2[TSource,TLocal].<ForEachWorker>b__0 (System.Int32 i)
Parallel+<>c__DisplayClass17_0`1[TLocal].<ForWorker>b__1 ()
Task.InnerInvoke ()
Task.InnerInvokeWithArg (System.Threading.Tasks.Task childTask)
Task+<>c__DisplayClass178_0.<ExecuteSelfReplicating>b__0 (System.Object <p0>)

Am I doing something wrong?
Same code in a classic foreach loop works flawlessly.

Thanks

@twcclegg
Copy link
Owner

twcclegg commented Nov 1, 2018

How big are your data sets? I been trying with 1000 contacts each with 10000 numbers (which takes a few minutes to run) and it's working just fine. Can you try using a ConcurrentBag instead?

@twcclegg
Copy link
Owner

twcclegg commented Nov 1, 2018

Perhaps you could see if you could reproduce the error using Regex directly since CapturingDigitPattern is static read only.

@nbsoftware
Copy link
Author

My datasets were even smaller than yours. 500 contacts, 100 numbers.
On what platform did you run your test?
I'll make some tests on the desktop and dig further on mobile using Regex directly and see how it goes.
It may very well be a Xamarin issue.
If so I'll post the issue on their repo.

@twcclegg
Copy link
Owner

twcclegg commented Nov 2, 2018

This was on .Net Framework 4.5.1

@nbsoftware
Copy link
Author

Having run multiple tests I confirm the exception is only thrown on an iOS device

Even the simulator works successfully although trying to run things in parallel on it doesn't seem to be quicker at all.

I'm trying for figure out what the next steps are...

@twcclegg
Copy link
Owner

Closing due to inactivity and various changes that likely effect behavior here, it is also known that dotnet regex performance is suboptimal on iOS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants