2

I have a model that is data bound to controls in a view. One of the bound properties (of type BindingList<T>) gets updated from another thread.

With help from this answer, I solved the "Cross-thread operation not valid" issue as follows (.NET 4.0, TPL):

public class Model : INotifyPropertyChanged
{
    private readonly TaskFactory _uiThreadTaskFactory =
        new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());

    private readonly object _myPropertyLocker = new object();

    private void Handler()
    {
        // In another thread

        _uiThreadTaskFactory.StartNew(
            () =>
                {
                    lock (_myPropertyLocker)
                    {
                        MyProperty.Add(someStuff);
                    }
                });
    }
}

This worked - until I tried to run my unit tests in ReSharper's test runner (v5.1). They threw the error

The current SynchronizationContext may not be used as a TaskScheduler.

on line

new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());

How can I resolve this as elegantly as possible?

Community
  • 1
  • 1
TrueWill
  • 25,132
  • 10
  • 101
  • 150
  • 2
    Are you using NUnit? http://stackoverflow.com/questions/8245926/nunit-tests-the-current-synchronizationcontext-may-not-be-used-as-a-taskschedul – Luke Hutton Dec 15 '11 at 00:21
  • @LukeHutton - yes, NUnit. I think you found the issue. You might want to post that as an answer. :) Thanks! – TrueWill Dec 15 '11 at 00:25

1 Answers1

3

You need to provide a SynchronizationContext. Reference: The current SynchronizationContext may not be used as a TaskScheduler.

[SetUp]
public void TestSetUp()
{
  SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
}
Community
  • 1
  • 1
Luke Hutton
  • 10,612
  • 6
  • 33
  • 58
  • I ended up injecting a TaskScheduler into my model via the constructor - in production I pass `TaskScheduler.FromCurrentSynchronizationContext()`, in tests I pass `TaskScheduler.Current`. – TrueWill Dec 15 '11 at 16:53
  • 1
    Update: `CurrentThreadTaskScheduler` from [Samples for Parallel Programming with the .NET Framework](http://code.msdn.microsoft.com/ParExtSamples/Release/ProjectReleases.aspx) works better for testing than `TaskScheduler.Current`. – TrueWill Dec 16 '11 at 21:28