2016-03-21 88 views
2

此代码主要是图像处理,但我所经历的不是语法错误“我们认为它是线程化的东西”。我正在编写一个我没有写的应用程序。这些代码是几个.cpp/c#文件。它工作正常,但突然间它开始做这种奇怪的行为。执行顺序中的奇怪行为。线程,异步和等待包括

通常,用户拍摄一张照片,然后在switch()之前,控制步骤进入几个功能,最后在最后一个文件(1-> 6)中结束。当最后一个文件(6)结束执行时,控制流回(6-> 1),并且我们检索到第一个文件的“case”,然后输入switch(),执行并继续。

1:

 private async void measureButton_Click(object sender, RoutedEventArgs e) 
     { 
       // .. 
       // some code above 
       var result = await ((CaptureViewModel)DataContext).ProcessMeasurement(); // line 85 

      switch (result) // line 87 <<< Here the switch executes before line 85 finishes executing 
      { 
        // some code and cases below 
        // .... 

2:

public async Task<AnalyzeCode> ProcessMeasurement() 
{ 
    if (currentSession.Type == SessionType.Calibration) 
     return await TakeCalibrationImage(); 

    return AnalyzeCode.NoSessionSelected; 
} 

3:

public async Task<AnalyzeCode> TakeCalibrationImage() 
{ 
    if (calibrationData.Count < maxCalibrationImages) 
    { 
     try 
     { 
      var data = await cameraController.TakeMeasurement(currentSession.Calibration, SessionType.Calibration); 
      // some code below 
      // .. 

4:

public async Task<Measurement> TakeMeasurement(Calibration calibration, SessionType type) 
    { 
     try 
     { 
      switch (type) 
      { 
       case SessionType.Calibration: 
        // some code above 
        // .. 
        return await cameraClient.AnalyzeNextCalibrationAsync(); // line 518 Here it throws an exception error 
        // some code below 
        //.. 

5:

IObservable<Measurement>^ Client::AnalyzeNextCalibrationAsync() 
{ 
    return Observable::ObserveOn(
     Observable::SubscribeOn(
      Observable::Create<Measurement>(
       gcnew Func<IObserver<Measurement>^, Action^>(
       gcnew AnalyzeNextCalibrationSubscribeFactory(this), 
       &AnalyzeNextCalibrationSubscribeFactory::AnalyzeNext)), 
      Scheduler::TaskPool), 
     Scheduler::TaskPool); 
} 
class on_next_functor_3 
{ 
    public: 
      void operator()(const tuple<frame, frame>& pair) const 
      { 
       Action<Measurement>^ on_next_delegate = this->on_next_delegate; 
       on_next_delegate(ConvertToCalibrationMeasurement(pair)); 
      } 
}; 

6:

Measurement ConvertToCalibrationMeasurement(const tuple<frame, frame>& pair) 
{ 
     // ... 
     // more code above 
    auto result1 = find_calibration_pattern(master_image); // line 386 
    auto result2 = find_calibration_pattern(slave_image); // line 387 
// .. 
// some code 
// .. 
    return Measurement(// line 401 
     masterImage, 
     slaveImage, 
     ConvertToDateTime(master.time), 
     ConvertToTargets(result)); 
} // end of the function 

现在这里是最近的怪异行为。控制器进入6 ans并开始按语句执行语句,然后突然,控制器跳回到4,引发错误并一直返回到开始处并执行switch(),该错误在屏幕上弹出错误。然后,控制器最后回到line 387并继续执行该功能。所以从技术上讲,它在前面的语句执行完成之前执行switch()。然后,无论最终的结果如何,自从我们的“失败”情况已经执行之后,它将不会有用。

有没有人知道为什么会发生这种情况?这个问题会在哪里产生?以及如何解决它?由于

编辑:

输出窗口显示这个曾经提示错误(从switch())弹出:

Exception thrown: 'System.InvalidOperationException' in System.Reactive.Linq.dll 
The thread 0x1574 has exited with code 0 (0x0). 
Exception thrown: 'System.NullReferenceException' in App.exe 

而这发生在文件4号线518

catch()

线程窗口显示Main Thread从文件1-> 4一直具有控件(黄色箭头)。但是,一旦文件4调用5-> 6,则Main Thread失去控制,并且“黄色箭头”转到执行6的Worker Thread。现在,在执行6时,Main Thread将控制取回为4,引发异常并执行catch()但后来失去控制回到Worker Thread并继续执行6 ..这是正常的吗?我从来没有与线程合作过,但这不合逻辑,我从来没有看到“流程中断”,而执行一个功能回去,然后转发并继续。我喜欢学习的一部分,但它的混淆为一个noob ..

+3

如果您发布您的代码_as code_,而不是屏幕截图,会更好。 – ForceBru

+0

好的,我会的,但代码行编号仍然会出现? –

+1

@FirstStep,它不会,但你总是可以写一个评论像'// < - 错误在这里' – ForceBru

回答

0

两个可能的原因。

  1. 您可能会同时运行您的代码两次。可能同时在不同的线程上(如果是的话,应该很容易在调试器中看到,打开“线程”视图)。可能在同一个线程上(如果线程调用await,实现启动一些异步操作,线程变为空闲,并且再次调用await)。

  2. VS调试器并不总是可靠的。在调试多线程代码时,有时会看到奇怪的地址,但事实并非如此。要进行验证,请在行87中添加日志记录,例如Debug.WriteLine,如果这是C#。

+0

我监视线程窗口(我从来没有使用它)。我注意到,主线程一旦从文件4移动到5就变成了一个工作线程,但是一旦抛出异常就返回到主线程,这是正常的吗? (请参阅编辑部分了解更多详情)。我在第86行写了Debug.Writeline(result),我怎么看它的输出? –

+0

调试/ windows/output,显示以下内容的输出:调试 – Soonts

+0

您知道发布版本为什么可以正常工作吗? –