예제 #1
0
        private void CreateWithAsyncInit_CreateOnly(bool readOnly)
        {
            // create a new message with asynchronous initializer
            var message = LogFileMessage.CreateWithAsyncInit(readOnly, out _);

            CheckDefaultState(message, false, readOnly);

            // check that the message is marked for asynchronous initialization
            Assert.True(message.IsAsyncInitPending);

            // check whether the message reflects the desired read-only state
            Assert.Equal(readOnly, message.IsReadOnly);
        }
예제 #2
0
        private async Task CreateWithAsyncInit_FollowedByInitialize(bool readOnly, bool initInSameThread, bool withPropertyChanged)
        {
            // create a new message with asynchronous initializer
            var message = LogFileMessage.CreateWithAsyncInit(readOnly, out var initializer);

            CheckDefaultState(message, false, readOnly);             // checks IsInitialized

            // check that the message is marked for asynchronous initialization
            Assert.True(message.IsAsyncInitPending);

            // prepare data pulling some information out of the event handler
            SynchronizationContext handlerThreadSynchronizationContext = null;
            var changedPropertyNames = new List <string>();
            var handlerCalledEvent   = new ManualResetEventSlim(false);

            // the handler that is expected to be called on changes
            void PropertyChangedHandler(object sender, PropertyChangedEventArgs e)
            {
                handlerThreadSynchronizationContext = SynchronizationContext.Current;
                changedPropertyNames.Add(e.PropertyName);
                handlerCalledEvent.Set();
            }

            // run test in a separate thread that provides a synchronization context that allows to
            // marshal calls into that thread
            await mThread.Factory.Run(() => { Assert.NotNull(SynchronizationContext.Current); });

            // register the PropertyChanged event
            if (withPropertyChanged)
            {
                await mThread.Factory.Run(() => { message.PropertyChanged += PropertyChangedHandler; });
            }

            // callback that initializes the message
            void InitializeTest()
            {
                initializer.Initialize(
                    1,
                    DateTimeOffset.Parse("2020-01-01T12:00:00+01:00"),
                    2,
                    3,
                    "Log Writer",
                    "Log Level",
                    new TagSet("Tag"),
                    "Application",
                    "Process",
                    42,
                    "Some text");

                // check administrative properties
                Assert.True(message.IsInitialized);
                Assert.False(message.IsAsyncInitPending);

                // check message properties
                Assert.Equal(1, message.Id);
                Assert.Equal(DateTimeOffset.Parse("2020-01-01T12:00:00+01:00"), message.Timestamp);
                Assert.Equal(2, message.HighPrecisionTimestamp);
                Assert.Equal(3, message.LostMessageCount);
                Assert.Equal("Log Writer", message.LogWriterName);
                Assert.Equal("Log Level", message.LogLevelName);
                Assert.Equal(new TagSet("Tag"), message.Tags);
                Assert.Equal("Application", message.ApplicationName);
                Assert.Equal("Process", message.ProcessName);
                Assert.Equal(42, message.ProcessId);
                Assert.Equal("Some text", message.Text);

                if (initInSameThread)
                {
                    if (withPropertyChanged)
                    {
                        // the event handler should have been called only once in the same thread
                        // (the event handler is called directly as the registering thread is the same as the thread raising the event)
                        Assert.True(handlerCalledEvent.IsSet);
                        Assert.Equal(new string[] { null }, changedPropertyNames.ToArray());                         // null => all properties
                    }
                    else
                    {
                        // the event handler should not have been called
                        Assert.False(handlerCalledEvent.IsSet);
                    }
                }
            }

            // initialize the message either in the context of the thread that registered the handler
            // or in a different - the current - thread
            if (initInSameThread)
            {
                await mThread.Factory.Run(InitializeTest);
            }
            else
            {
                InitializeTest();
            }

            if (!initInSameThread)
            {
                // the thread registering the event and the thread initializing the message are different
                if (withPropertyChanged)
                {
                    // event handler should run in the context of the thread that registered it
                    Assert.True(handlerCalledEvent.Wait(1000));
                    Assert.Same(mThread.Context.SynchronizationContext, handlerThreadSynchronizationContext);
                    Assert.Equal(new string[] { null }, changedPropertyNames.ToArray());
                }
                else
                {
                    // the event handler should not have been called
                    Assert.False(handlerCalledEvent.Wait(1000));
                }
            }
        }