此问题已在此处有答案:
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,它仍然抛出异常。我不知道怎么用。
2条答案
按热度按时间vpfxa7rd1#
其实我用错了调度器:
而不是
这暂时解决了问题。
xzv2uavs2#
命名空间System.Timers中的类型Timer默认创建一个新线程来运行计时器。在大多数编程环境中,尝试从未创建用户界面控件的线程直接修改或访问User Interface元素会引发异常InvalidOperationException,该异常告诉您仅更新来自较新线程的变量,然后使用类中更新的变量更新UI。