差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录前一修订版后一修订版 | 前一修订版 | ||
it:dotnet:线程保护 [2023-08-24 07:34] – goldentianya | it:dotnet:线程保护 [2023-08-24 07:44] (当前版本) – goldentianya | ||
---|---|---|---|
行 1: | 行 1: | ||
====== 线程保护 ====== | ====== 线程保护 ====== | ||
+ | 使用 lock (lockObject) 或者 | ||
< | < | ||
Task.Run(() => | Task.Run(() => | ||
{ | { | ||
Monitor.Enter(lockObject); | Monitor.Enter(lockObject); | ||
- | try | + | |
- | { | + | { |
- | GetActiveDataGrid().SelectedItem = item; | + | GetActiveDataGrid().SelectedItem = item; |
- | }catch (Exception e) | + | }catch (Exception e) |
+ | { | ||
+ | // ... | ||
+ | } | ||
+ | finally | ||
+ | { | ||
+ | Monitor.Exit(lockObject); | ||
+ | } | ||
+ | }); | ||
+ | </ | ||
+ | |||
+ | ===== Dispatcher.Invoke vs BeginInvoke ===== | ||
+ | |||
+ | |||
+ | 使用 Dispatcher.Invoke 来实现相同的跨线程访问控制。InvokeRequired 来检查当前线程是否为主线程 如果不是,则使用 BeginInvoke 来将设置操作委托到主线程。 | ||
+ | <code > | ||
+ | if (InvokeRequired) | ||
+ | { | ||
+ | BeginInvoke(new Action< | ||
+ | | ||
+ | SetValue(value); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | `BeginInvoke` 和 `Dispatcher.Invoke` 都是用于在 UI 线程(主线程)上执行委托(函数)的方法,从而在跨线程操作中保持正确性。它们主要用于在多线程环境中从非 UI 线程调用 UI 元素的操作,以确保线程安全性。 | ||
+ | |||
+ | 1. **`BeginInvoke`**: | ||
+ | - `BeginInvoke` 是 `Control` 类的方法,适用于 Windows 窗体应用程序中。 | ||
+ | - 通过 `BeginInvoke`,您可以将一个委托安排在 UI 线程的消息队列中执行,但不会阻塞当前线程。 | ||
+ | - `BeginInvoke` 返回一个 `IAsyncResult`,您可以使用它来等待操作的完成或检查状态。 | ||
+ | - 由于不会阻塞当前线程,因此 `BeginInvoke` 允许在执行操作的同时继续执行其他任务。 | ||
+ | |||
+ | 示例使用 `BeginInvoke` 将委托放入 UI 线程的消息队列中,以确保在 UI 线程上执行操作: | ||
+ | |||
+ | |||
+ | <code > | ||
+ | if (InvokeRequired) | ||
{ | { | ||
+ | BeginInvoke(new Action(() => | ||
+ | { | ||
+ | // 在 UI 线程上执行操作 | ||
+ | })); | ||
} | } | ||
- | finally | + | else |
{ | { | ||
- | Monitor.Exit(lockObject); | + | // 在 UI 线程上执行操作 |
} | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | 2. **`Dispatcher.Invoke`**: | ||
+ | - `Dispatcher.Invoke` 是 `Dispatcher` 类的方法,适用于 WPF 应用程序中。 | ||
+ | - 类似于 `BeginInvoke`,`Dispatcher.Invoke` 也将委托放入 UI 线程的消息队列中执行,但与 `BeginInvoke` 不同,它会阻塞当前线程,直到委托完成执行。 | ||
+ | - `Dispatcher.Invoke` 返回执行结果(或 `null`),因此可以用于同步等待操作完成。 | ||
+ | |||
+ | 示例使用 `Dispatcher.Invoke` 在 UI 线程上执行操作,并等待其完成: | ||
+ | |||
+ | |||
+ | < | ||
+ | Dispatcher.Invoke(() => | ||
+ | { | ||
+ | // 在 UI 线程上执行操作 | ||
}); | }); | ||
</ | </ | ||
+ | |||
+ | |||
+ | 总之,无论是 `BeginInvoke` 还是 `Dispatcher.Invoke`,它们的目标都是在 UI 线程上执行操作,确保线程安全性。选择哪种方法取决于您是否需要当前线程继续执行其他任务(使用 `BeginInvoke`),或者需要等待操作完成并获取其结果(使用 `Dispatcher.Invoke`)。 | ||
+ | |||
+ | ===== 判断主线程 ===== | ||
+ | 在 winform 中可以使用 <color # | ||
+ |