0

this is modelled on a answer to a previous question How to display a clock with the current time in a Windows Core IoT app?, I get an exception: "The application called an interface that was marshalled for a different thread." If I change the property with an click event, the binding works.

public class RunClock: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    ThreadPoolTimer _clockTimer = null;
    private string clock="";
    public string Clock
    {
        set
        {
            clock= value;
            this.OnPropertyChanged();
        }
        get { return clock; } }
    public RunClock()
    {

        _clockTimer = ThreadPoolTimer.CreatePeriodicTimer(_clockTimer_Tick, TimeSpan.FromMilliseconds(1000));            
    private void _clockTimer_Tick(ThreadPoolTimer timer)
    {
        DateTime datetime = DateTime.Now;
        Str1 = datetime.ToString();
    }
    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

and the Xaml:

<TextBlock Margin="15" Name="timec" Text="{x:Bind Path=RunClock.Clock, Mode=OneWay}"></TextBlock>

Thank you in advance!

Update, working code:

 public class test : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    ThreadPoolTimer _clockTimer = null;
    private string str1 = "";
    public string Str1
    {
        set
        {
            str1 = value;
            this.OnPropertyChanged();
        }
        get { return str1; }
    }
    public test()
    {

        _clockTimer = ThreadPoolTimer.CreatePeriodicTimer(_clockTimer_Tick, TimeSpan.FromMilliseconds(1000));
                }
    async private void _clockTimer_Tick(ThreadPoolTimer timer)
    {
       await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() =>
        {
            DateTime dt = DateTime.Now;
            Str1 = dt.ToString();
        });
    }
    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Xaml (test1 is an instance of he viewmodel):

                <TextBlock Margin="15" Name="timec" Text="{x:Bind test1.Str1, Mode=OneWay}"></TextBlock>
Community
  • 1
  • 1
rur2641
  • 691
  • 1
  • 10
  • 26

1 Answers1

0

Exception is because your trying to modify UI in different thread

Use this

 private void _clockTimer_Tick(ThreadPoolTimer timer)
    {
       var dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher;
       await dispatcher.RunAsync(
        CoreDispatcherPriority.Normal, () =>
        {
        // Your UI update code goes here!
        DateTime datetime = DateTime.Now;
        Str1 = datetime.ToString();
        });
    }
Archana
  • 3,213
  • 1
  • 15
  • 21
  • With your code I got 'System.NullReferenceException' "Additional information: Object reference not set to an instance of an object." But I searched it and found Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() =>{ ui code }); and it worked. Thank you! – rur2641 May 04 '16 at 01:24
  • @rur2641 Yes. Actually I meant that. I ll update the answer – Archana May 04 '16 at 04:42
  • can you please check this question? http://stackoverflow.com/questions/37508726/using-threadpooltimer-with-background-audio-uwp – yalematta May 29 '16 at 10:23
  • 1
    I posted the working code. It was to have a running clock displayed. – rur2641 May 29 '16 at 11:22