【问题标题】:c# wpf - multithreadingc# wpf - 多线程
【发布时间】:2018-05-04 18:29:41
【问题描述】:

我正在使用 C# wpf 并想拍摄一张相机照片,然后在完成事件调用后 - 更改 MainWindow 中的一些控件。问题是在与主线程不同的线程中调用事件,并且为了运行我的 NextState 函数(更改一些控件),它需要是主线程(否则我会收到带有警告的消息框并且没有任何反应)。这是我的代码:

public partial class PhotoCapture : UserControl
{
    private bool ready;
    private System.Timers.Timer timer;
    private readonly Object lockObj = new Object();

    public PhotoCapture(PhotoCaptureState photoCaptureState)
    {
        InitializeComponent();

        ready = false;
        PictureManager.LoadCompleted += PictureManager_LoadCompleted;
        CameraManager.TakePicture();
        timer = new System.Timers.Timer(200);
        timer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
        timer.Enabled = true;
    }

    private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        bool change = false;
        lock(lockObj)
        {
            if (ready)
            {
                change = true;
            }
        }
        if (change)
        {
            MessageBox.Show("ready");
            timer.Enabled = false;
            PictureManager.LoadCompleted -= PictureManager_LoadCompleted;
            NextState();
        }
    }

    private void PictureManager_LoadCompleted()
    {
        lock (lockObj)
        {
            ready = true;
        }
    }

    private void NextState()
    {
        MainWindow wnd = (MainWindow)Application.Current.MainWindow;
        App app = (App)wnd.contentControl.Content;
        app.NextState();
    }
}

有趣的是,我收到了几个“就绪”消息框,看起来 NextStage 根本没有执行。我不知道它为什么会这样。我会很感激任何帮助

【问题讨论】:

  • 在不同的线程中执行,也做了一些测试,在新线程中不断执行Timer_Elapsed(当前线程的id在增加)

标签: c# wpf multithreading


【解决方案1】:

从主 UI 线程分离出来的后台线程无法更新在 UI 线程上创建的元素的内容。为了让后台线程访问 UI 的属性,后台线程必须将工作委托给与 UI 线程关联的 Dispatcher。

在您的 Timer_Elapsed 类中,您需要调用调度程序来完成您的 UI 工作。你可以阅读Dispatcherhere

或者您可以尝试使用DispatcherTimer。 DispatcherTimer 在 UI 线程上触发它的 Tick 事件,你可以对 UI 做任何你想做的事情。可以看例子here

【讨论】:

    【解决方案2】:

    你是对的,它是在不同的线程上执行的。

    您可以使用Dispatcher 在主线程上调用NextState() 方法。

    Dispatcher.Invoke(() = > NextState());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-16
      • 2016-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多