Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 调用onclick on按钮会在C中的另一个线程中抛出代码#_C#_Wpf_Multithreading_User Interface_Asynchronous - Fatal编程技术网

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()正常工作,您介意演示一个简单的示例吗?我一直在找,但似乎什么都不适合我。