(C# WPF)WindowBase.dll中的System.Timers.Timer和InvalidOperationException [重复]

eqoofvh9  于 12个月前  发布在  C#
关注(0)|答案(2)|浏览(158)

此问题已在此处有答案

Confusion about what the WPF Dispatcher object is(2个答案)
上个月关门了。
我有一个名为 Recorder 的类,其中包含一个 * System.Timers.Timer *,它会重复地滴答作响。

internal class Recorder
    {
        const double TimeIntervalMilliseconds = 20;
        readonly Timer Timer;
        readonly IFeed Feed;
        readonly ISessionDataSink Data;
        readonly bool IsLooped;
        RecorderState state;
        public event EventHandler<RecorderState>? StateChanged;

        public Recorder(IFeed feed, ISessionDataSink data, bool isLooped)
        {

            Feed = feed;
            Data = data;
            IsLooped = isLooped;
            state = RecorderState.Initial;
            Timer = new(TimeIntervalMilliseconds)
            {
                AutoReset = true
            };
            Timer.Elapsed += OnTimeElapsed;
        }
    ///
    ///omitted members
    ///
    }

还有一个 Package 器RecorderViewModel,它公开一些命令并侦听 Recorder 的StateChanged事件。问题是,有时它抛出InvalidOperationException,而没有任何额外的细节。该异常写入到异常的输出中。它不会停止程序,但与命令相关联的按钮未被适当禁用。

internal class RecorderViewModel
    {
        readonly Recorder Recorder;
        readonly RelayCommand PauseCommandField;
        readonly RelayCommand ResetCommandField;

        public RecorderViewModel(Recorder recorder)
        {
            Recorder = recorder;
            Recorder.StateChanged += OnStateChanged;
            PauseCommandField = new(Pause, CanPause);
            ResetCommandField = new(Reset, CanReset);
        }
        //
        // Omitted members
        //
        void OnStateChanged(object? sender, RecorderState state)
        {
            PauseCommandField.RaiseCanExecuteChanged(); //'System.InvalidOperationException' in WindowsBase.dll      
            ResetCommandField.RaiseCanExecuteChanged();
        }
    }

当我使用断点进行调试时,它加载文件ExecutionContext.cs并转到方法:

internal static void RunInternal(ExecutionContext executionContext, ContextCallback callback, object state)

它看起来像是与多线程有关,我不是这方面的Maven。我试着使用 *Dispatcher. Beginaplake *,它没有抛出异常,但是按钮仍然没有被适当地禁用。
我还尝试设置一个SynchronizingObject,它仍然抛出异常。我不知道怎么用。

vpfxa7rd

vpfxa7rd1#

其实我用错了调度器:

System.Windows.Threading.Dispatcher.CurrentDispatcher

而不是

App.Current.Dispatcher

这暂时解决了问题。

xzv2uavs

xzv2uavs2#

命名空间System.Timers中的类型Timer默认创建一个新线程来运行计时器。在大多数编程环境中,尝试从未创建用户界面控件的线程直接修改或访问User Interface元素会引发异常InvalidOperationException,该异常告诉您仅更新来自较新线程的变量,然后使用类中更新的变量更新UI。

相关问题