Вызывающий поток должен быть STA, потому что многие компоненты пользовательского интерфейса требуют этого

Я нашел на веб-сайте все об ответе на этот вопрос, код изменяется в следующий формат, больше не является ошибкой, но делегат не выполняет оператор внутри, Что не так? Кто-нибудь может мне помочь? Моя программа использует мультимедийный таймер каждые 2 секунды, чтобы нарисовать точку кривой, нарисовать кривую с помощью Visifire

Thread Messagethread = new Thread(new ThreadStart(delegate() {
                DispatcherOperation DispacherOP = Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal, 
                    new Action(delegate() {
                    ChartData.Add(new Tuple<string, double>("A" + seed.NextDouble(), 1.5 + seed.Next(10)));
                })); 
            }));
            Messagethread.SetApartmentState(ApartmentState.STA);
            Messagethread.Start();

Моя страница ViewModel:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows;
using System.Collections.ObjectModel;
using Dongzr.MidiLite;
using System.Windows.Threading;
using System.Threading;

namespace WpfVisifire
{
    public class ChartViewModel
    {
        static MmTimer timer1;
        static DispatcherTimer timer2;

        private static readonly Random seed = new Random();
        public ObservableCollection<Tuple<string, double>> ChartData
        {
            get;
            private set;
        }

        public ChartViewModel()
        {
            StopDataCommand = new RelayCommand((p) => stop());
            ChangeVisiChartDataCommand = new RelayCommand((p) => changeData());
            ChartData = new ObservableCollection<Tuple<string, double>>();
            timer1 = new MmTimer();
        }
        public ICommand StopDataCommand
        {
            get;
            private set;
        }
        public ICommand ChangeVisiChartDataCommand
        {
            get;
            private set;
        }
        private void changeData()
        {
            timer1.Mode = MmTimerMode.Periodic;
            timer1.Interval = 2000;
            timer1.Tick += new EventHandler(timer1_Tick);
            timer1.Start();           
        }

        void timer1_Tick(object sender, EventArgs e)
        {
           /*Dispatcher.CurrentDispatcher.BeginInvoke(
                 DispatcherPriority.Normal,
                 new Action(
                     delegate()
                     {
                         ChartData.Add(new Tuple<string, double>("A" + seed.NextDouble(), 1.5 + seed.Next(10)));
                     }));*/
            Thread Messagethread = new Thread(new ThreadStart(delegate() {
                DispatcherOperation DispacherOP = Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal, 
                    new Action(delegate() {
                    ChartData.Add(new Tuple<string, double>("A" + seed.NextDouble(), 1.5 + seed.Next(10)));
                })); 
            }));
            Messagethread.SetApartmentState(ApartmentState.STA);
            Messagethread.Start(); 
        }

        private void stop()
        {
            timer1.Stop();
            timer1.Dispose();
            //.Show("jeighier");
        }

    }
}`

MainWindow.xaml

<Window x:Class="WpfVisifire.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vCharts="clr-namespace:Visifire.Charts;assembly=WPFVisifire.Charts"
        xmlns:vm="clr-namespace:WpfVisifire"
        Title="MainWindow" Height="600" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <vm:ChartViewModel x:Key="chartViewModel" />
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <StackPanel DataContext="{Binding Source={StaticResource chartViewModel}}">
            <WrapPanel Orientation="Horizontal">
                <Button Content="Start" Height="28" Name="Add" Margin="5" Width="125" Command="{Binding Path=ChangeVisiChartDataCommand}"/>
                <Button Margin="5" Height="28" Width="125" Content="Stop" Command="{Binding Path=StopDataCommand}" />
            </WrapPanel>

            <vCharts:Chart Watermark="False" Theme="Theme1" Width="480" Height="479" x:Name="MyChart"
                            AnimationEnabled="True" AnimatedUpdate="True">
                <vCharts:Chart.Titles>
                    <vCharts:Title Text="This is a chart" FontSize="12" />
                    <vCharts:Title Text="This is another chart" FontSize="10" HorizontalAlignment="Right" />
                </vCharts:Chart.Titles>
                <vCharts:Chart.AxesX>
                    <vCharts:Axis Title="horizontal title" />
                </vCharts:Chart.AxesX>
                <vCharts:Chart.AxesY>
                    <vCharts:Axis Title="vertical title" />
                </vCharts:Chart.AxesY>
                <vCharts:Chart.Series>
                    <vCharts:DataSeries x:Name="dataSeries" RenderAs="Line"  DataSource="{Binding Path=ChartData}">
                        <vCharts:DataSeries.DataMappings>
                            <vCharts:DataMapping MemberName="AxisXLabel" Path="Left" />
                            <vCharts:DataMapping MemberName="YValue" Path="Right" />
                        </vCharts:DataSeries.DataMappings>
                    </vCharts:DataSeries>
                </vCharts:Chart.Series>
            </vCharts:Chart>
        </StackPanel>
    </Grid>
</Window>

2 ответа

Решение

Попробуйте выполнить процедуру рисования в вашем обработчике Tick. Если тик-обработчик не выполняется в главном потоке, сохраните экземпляр Dispatcher в локальной переменной и инициализируйте его в

public ChartViewModel()

как это:

myDispatcher=Dispatcher.CurrentDispatcher

затем используйте myDispatcher.Invoke в обработчике тиков таймера

Попробуйте что-нибудь попроще

timer1.Tick += (o,e) => Dispatcher.BeginInvoke((Action)(() => 
     ChartData.Add(Tuple.Create("A" + seed.NextDouble(), 1.5 + seed.Next(10)))); 
Другие вопросы по тегам