C# 从UI线程同步访问资源

C# 从UI线程同步访问资源,c#,synchronization,locking,ui-thread,C#,Synchronization,Locking,Ui Thread,I在全局对象上锁定,以便从各个线程同步与外部设备的通信,该线程工作正常 我想使用滑块控件来设置值,然后将这些值发送到外部设备,因此在将更改发送到设备之前,我使用其滚动事件来侦听更改 问题是,在与设备通信之前,我需要锁定全局对象,如下所示: private void slider_Scroll(object sender, EventArgs e) { lock(lockObject) { //send slider values to external devic

I
在全局对象上锁定
,以便从各个线程同步与外部设备的通信,该线程工作正常

我想使用
滑块
控件来设置值,然后将这些值发送到外部设备,因此在将更改发送到设备之前,我使用其
滚动
事件来侦听更改

问题是,在与设备通信之前,我需要锁定全局对象,如下所示:

private void slider_Scroll(object sender, EventArgs e)
{
    lock(lockObject)
    {
        //send slider values to external device
    }
}
在试图获得
锁时,上述操作总是无限期挂起。我的其余代码工作正常,因此我认为我没有真正的竞争条件——我假设这是因为它在UI线程上运行,在UI线程上阻塞是个坏主意?我可能错了

但是,如果是这种情况,我猜我需要将上述代码包装在一个方法中,并在UI线程的“main”线程上以某种方式调用它


如何实现这一点?

从主UI线程使用
锁肯定不是一个好主意。将BackgroundWorker()控件添加到表单中,并将滑块值传递到RunWorkerAsync()方法中。您可以通过
e.Argument
检索DoWork()处理程序中的值,并从中安全地使用
lock

非常感谢您的回答。我想这可能会奏效。每次移动滑块时,是否会有大量的开销来吸引后台工作人员?是否可以改用委托?如果您在BackgroundWorker()已运行时再次尝试运行它,它将引发异常。您可以检查它的IsBusy()属性以决定是否运行它。不管是什么方法,等待控件停止更改并只发送最后一个值可能更有意义。你到底在用什么控件?..“slider”可以是几个不同的控件。只是一个Windows窗体的“slider”。发送最后一个值很简单,谢谢。为了从外部设备读取值,我想我必须通过BackgroundWorker的RunWorkerCompleted事件将值返回到UI元素?是的……如果将WorkerReportsProgress()设置为True,则可以使用ReportProgress()和ProgressChanged()事件。