-1

I have a code like this:

private static var Locker = new Object();

private void SensitiveCode()
{
    lock (Locker)
    {
        SomeCodeSensitive(); .....
        Dispatcher.BeginInvoke(new Action(() =>
        {
            SomeCodeThatUpdatesUI();
        }));
        MoreCodeSensitive();
    }
}

Also i have a thread running doing something like this:

while (X)
{
    SensitiveCode();
    Thread.Sleep(5000);
}

Now in my main thread I sometimes call SensitiveCode(); SensitiveCode() is on lock because it must not be called from 2 threads at same time.

Well, the problem is I don't know why, sometimes i find a deadlock, sometimes on UI (the UI freezes), sometimes on thread. I don't know what is happening, one of the threads stops in lock() cause it is supposed that variable "Locker" is in use for the other thread, but that is not true. I think that the problem could be the BeginInvoke inside the lock, but I think that should not be enough to lock this code.

Also, it is very hard to reproduce the problem, I've been testing for 3 hours and it has appeared only 2 times.

Does someone know what could it be?

Thanks!

Update Due to questions:

SensitiveCode() is doing work with some AsyncObservableCollection objects (class from http://www.thomaslevesque.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/) .

Doing things like reading from database and filling those AsyncObservableCollection(). I lock this action because I cannot allow the thread updates my AsyncObservableCollection while the user does it at the same time.

Also, the UI does this

Dispatcher.BeginInvoke(new Action(() =>
        {
            if (tables.Count != TablesInWindow.Count)               
                TablesInWindow.ClearAndAddRange(tables);                
            else
            {
                if (tables.Where((t, i) => !TablesInWindow[i].Equals(t)).Any())                                            
                    TablesInWindow.ClearAndAddRange(tables);

            }

            ButtonPageBack.IsEnabled = canGoBack;
            ButtonPageNext.IsEnabled = canGoFoward;
        }));

Update 2:

After doing again, here is a screenshot of the threads when the deadlock ocurred

http://i.imgur.com/8xyIy6h.png

MovePageForward is the action I do on the UI, it contains this code:

public static void MakePageForward()
    {            
        lock (ConfigParameters.Lock)
        {
            _currentPage++;
            ShowTablesInWindow();
        }
    }

TimerConnectionTick has the following code:

private static void TimerConnectionTick()
    {
        while (!_thisDisposing)
        {
            ShowTablesInWindow();

            if (!_thisDisposing)
                Thread.Sleep(5000);
        }
    }
Rafa S.
  • 17
  • 5
  • Are you use you are not using Dispatcher.Invoke or locking somewhere below the callstack (in SomeCodeSensitive or MoreCodeSensitive parts)? – Evk Mar 10 '17 at 16:18
  • Can you add more context to your sample, something that can be used to reproduce the issue. Both the `lock` and `thread.Sleep` will block whatever thread is trying to enter, again more context is needed. A couple of oddities: the `Dispatcher` is not _sensitive code_ why is it locked? and `Locker` is not a sensitive object why is it used for the lock, how many sensitive objects are touched within the lock block? – JSteward Mar 10 '17 at 16:49
  • None Dispatcher.Invoke code in SensitiveCode. – Rafa S. Mar 10 '17 at 17:25
  • Well... It is not sensitive code, I could bring it out from lock, but I don't know why it would help. Anyway, my problem is that I cannot reproduce this problem. It has happened me in 5 hours of testing 3 times, it's really a headache. I will try to bring out the BeginInvoke code and send it to customers so they test it in real enviroment cause I don't know what more to do... Locker is an object I use to use to lock, it is not sensitive it is only a new object(). What I touch in sensitive code are calls to database and updating AsyncObservableCollection objects. – Rafa S. Mar 10 '17 at 18:02

1 Answers1

0

Without seeing all of your code, it is hard to debug. Is it possible that somewhere within your SomeCodeThatUpdatesUI() method you are also triggering a lock on Locker? If you are triggering a lock recursively it will pass through without issue, however if you are doing so within your BeginInvoke on the Dispatcher thread (which may be different than your current thread as you mentioned you call this from different threads), it will lock and cause a Deadlock.

If that is the case, perhaps you can either refactor when you need to lock, or use something like a ReaderWriterLockSlim (https://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim(v=vs.110).aspx)

Adam Dove
  • 21
  • 4
  • Updated question with more info – Rafa S. Mar 10 '17 at 17:31
  • I see your updates, however I can only guess as to what the rest of your code is doing, and how many entry points each lock has. Are you sure that the deadlock is occurring on the Locker lock? If you can cause it to happen again, capture a dump file from the process and look at the call stack of the active threads. – Adam Dove Mar 10 '17 at 19:41
  • Yes, i did it and look the image i link: – Rafa S. Mar 13 '17 at 08:18