差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
后一修订版
前一修订版
it:dotnet:线程保护 [2023-08-24 07:34] goldentianyait:dotnet:线程保护 [2023-08-24 07:44] (当前版本) goldentianya
行 1: 行 1:
 ====== 线程保护 ====== ====== 线程保护 ======
  
 +使用 lock (lockObject) 或者  Monitor.Enter(lockObject)
 <code> <code>
 Task.Run(() => Task.Run(() =>
 { {
   Monitor.Enter(lockObject);   Monitor.Enter(lockObject);
-try +  try 
-+  
-GetActiveDataGrid().SelectedItem = item; +    GetActiveDataGrid().SelectedItem = item; 
-}catch (Exception e)+  }catch (Exception e
 +  { 
 +    // ... 
 +  } 
 +  finally 
 +  { 
 +    Monitor.Exit(lockObject); 
 +  } 
 +}); 
 +</code> 
 + 
 +===== Dispatcher.Invoke vs BeginInvoke ===== 
 + 
 + 
 +使用 Dispatcher.Invoke 来实现相同的跨线程访问控制。InvokeRequired 来检查当前线程是否为主线程 如果不是,则使用 BeginInvoke 来将设置操作委托到主线程。 
 +<code > 
 + if (InvokeRequired) 
 + { 
 +    BeginInvoke(new Action<int>(SetValue), value); 
 + }else{ 
 +    SetValue(value); 
 + } 
 +</code> 
 + 
 +`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 线程上执行操作
 } }
 +</code>
 +
 +
 +2. **`Dispatcher.Invoke`**:
 +   - `Dispatcher.Invoke` 是 `Dispatcher` 类的方法,适用于 WPF 应用程序中。
 +   - 类似于 `BeginInvoke`,`Dispatcher.Invoke` 也将委托放入 UI 线程的消息队列中执行,但与 `BeginInvoke` 不同,它会阻塞当前线程,直到委托完成执行。
 +   - `Dispatcher.Invoke` 返回执行结果(或 `null`),因此可以用于同步等待操作完成。
 +
 +示例使用 `Dispatcher.Invoke` 在 UI 线程上执行操作,并等待其完成:
 +
 +
 +<code>
 +Dispatcher.Invoke(() =>
 +{
 +    // 在 UI 线程上执行操作
 }); });
 </code> </code>
 +
 +
 +总之,无论是 `BeginInvoke` 还是 `Dispatcher.Invoke`,它们的目标都是在 UI 线程上执行操作,确保线程安全性。选择哪种方法取决于您是否需要当前线程继续执行其他任务(使用 `BeginInvoke`),或者需要等待操作完成并获取其结果(使用 `Dispatcher.Invoke`)。
 +
 +===== 判断主线程 =====
 +在 winform 中可以使用 <color #ff7f27>''%%InvokeRequired%%''</color>,在WPF中可以使用 <color #ff7f27>''%%Dispatcher.CheckAccess()%%''</color>
 +
it/dotnet/线程保护.1692862499.txt.gz · 最后更改: 2023-08-24 07:34 由 goldentianya
回到顶部
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0