C# 调用onclick on按钮会在C中的另一个线程中抛出代码#
我有一个启动照相机的按钮。有时我想启动相机,不按按钮,直接抛出代码 守则:C# 调用onclick on按钮会在C中的另一个线程中抛出代码#,c#,wpf,multithreading,user-interface,asynchronous,C#,Wpf,Multithreading,User Interface,Asynchronous,我有一个启动照相机的按钮。有时我想启动相机,不按按钮,直接抛出代码 守则: private async void StartCamera() { if (!CameraList.HasItems) //-------> CameraList is in the UI { MessageArea.Text = "No cameras found; cannot start processing"; return; } // C
private async void StartCamera()
{
if (!CameraList.HasItems) //-------> CameraList is in the UI
{
MessageArea.Text = "No cameras found; cannot start processing";
return;
}
// Clean leading/trailing spaces in API keys.
Properties.Settings.Default.FaceAPIKey = Properties.Settings.Default.FaceAPIKey.Trim();
Properties.Settings.Default.EmotionAPIKey = Properties.Settings.Default.EmotionAPIKey.Trim();
Properties.Settings.Default.VisionAPIKey = Properties.Settings.Default.VisionAPIKey.Trim();
// Create API clients.
_faceClient = new FaceServiceClient(Properties.Settings.Default.FaceAPIKey);
_emotionClient = new EmotionServiceClient(Properties.Settings.Default.EmotionAPIKey);
_visionClient = new VisionServiceClient(Properties.Settings.Default.VisionAPIKey);
// How often to analyze.
_grabber.TriggerAnalysisOnInterval(Properties.Settings.Default.AnalysisInterval);
// Reset message.
MessageArea.Text = ""; // -------> MessageArea is in the UI
// Record start time, for auto-stop
_startTime = DateTime.Now;
await _grabber.StartProcessingCameraAsync(CameraList.SelectedIndex); // This is the problem, with the previous two I just can skip it, but here I can't avoid the CameraList
}
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
StartCamera();
}
我必须说明CameraList变量是一个UI组合框
所以当我尝试使用StartCamera函数时,我得到一个异常,它说
{“调用线程无法访问此对象,因为其他线程拥有它。”}
当我尝试使用startButton UI并使用以下命令时,也会发生同样的情况:
StartButton.RaiseEvent(new RoutedEventArgs(System.Windows.Controls.Primitives.ButtonBase.ClickEvent));
在前一个线程中,我被告知:“您只能从最初创建UI元素的线程(即UI线程)访问UI元素。因此,您不能在后台线程上运行代码。这与您最初关于如何调用事件处理程序的问题无关。如果您有其他问题,请提出新问题。”
所以我来了。我本来想为您发布一些示例代码,但是在这个帖子上有很多很好的答案 基本上,您必须使用委托来回调ui运行的线程。这是因为您希望序列化所有ui修改/输入。您不希望两个不同的线程同时更改ui中的某些内容。根据我的经验,用锁来包围你要调用的方法也不是一个坏主意,就像增加了一层对竞争条件的保护一样
不管怎样,看看那个链接。它应该可以帮助您解决问题。您需要指定哪一行抛出execption。另外,对于非事件处理程序的任何内容,异步void是一个坏习惯。改为使用函数
async Task
。根据标记的副本,可以使用多种方法,但在您的情况下,Dispatcher.Invoke()
似乎最合适。您需要使用Dispatcher.invoke()
调用调用StartCamera()
或StartButton.RaiseEvent()
的代码。更好的是,使用良好的MVVM实践,这样您就不会直接分配给MessageArea.Text
和其他直接访问导致您出现问题的UI对象,然后您可以直接调用StartCamera()
,而无需Dispatcher.Invoke()
和WPF将自动为您处理跨线程行为。编辑后的CameraList和MessageArea变量基本上都在UI中。我可以跳过这两行,但不能跳过包含CameraList的代码的最后一个返回行。我似乎无法使dispatcher.Invoke()正常工作,您介意演示一个简单的示例吗?我一直在找,但似乎什么都不适合我。