主頁 > .NET開發 > SynchronizationContext(同步背景關系)綜述

SynchronizationContext(同步背景關系)綜述

2020-09-19 00:05:55 .NET開發

>>回傳《C# 并發編程》

  • 1. 概述
  • 2. 同步背景關系 的必要性
    • 2.1. ISynchronizeInvoke 的誕生
    • 2.2. SynchronizationContext 的誕生
  • 3. 同步背景關系 的概念
  • 4. 同步背景關系 的實作
    • 4.1. WinForm 同步背景關系
    • 4.2. Dispatcher 同步背景關系
    • 4.3. Default 同步背景關系
    • 4.4. 背景關系捕獲和執行
    • 4.5. AspNetSynchronizationContext
  • 5. 同步上下實作類 的注意事項
  • 6. AsyncOperationManager 和 AsyncOperation
  • 7. 同步背景關系 的Library支持示例
    • 7.1. WCF
    • 7.2. Workflow Foundation (WF)
    • 7.3. Task Parallel Library (TPL)
    • 7.4. Reactive Extensions (Rx)
    • 7.5. 異步編程 Async
  • 8. 限制和功能

1. 概述

注意: 本篇文章講述的是在 .Net Framework 環境下的分析, 但是我相信這與 .Net Core 設計思想是一致,但在實作上一定優化了很多,

下面開始本次講述:

無論是什么平臺(ASP.NET 、WinForm 、WPF 等),所有 .NET 程式都包含 同步背景關系 概念,并且所有多執行緒編程人員都可以通過理解和應用它獲益,

2. 同步背景關系 的必要性

2.1. ISynchronizeInvoke 的誕生

  • 原始多執行緒

    • 多執行緒程式在 .NET Framework 出現之前就存在了,
    • 這些程式通常需要一個執行緒將一個作業單元傳遞給另一個執行緒
    • Windows 程式圍繞訊息回圈進行,因此很多編程人員使用這一內置佇列傳遞作業單元
    • 每個要以這種方式使用 Windows 訊息佇列的多執行緒程式都必須自定義 Windows 訊息以及處理約定
  • ISynchronizeInvoke 的誕生

    • .NET Framework 首次發布時,這一通用模式是標準化模式,
    • 那時 .NET 唯一支持的 GUI 應用程式型別是 WinFrom,
    • 不過,框架設計人員期待其他模型,他們開發出了一種通用的解決方案,ISynchronizeInvoke 誕生了,
  • ISynchronizeInvoke 的原理

    • 一個“源”執行緒可以將一個委托列入“目標”執行緒佇列,
    • ISynchronizeInvoke 還提供了一個屬性來確定當前代碼是否已在目標執行緒上運行,
    • WinForm 提供了單例的 ISynchronizeInvoke 實作,并且開發了一種模式來設計異步組件

2.2. SynchronizationContext 的誕生

  • ASP.NET 異步頁面
    • .NET Framework 2.0 版包含很多重大改動, 其中一項重要改進是在 ASP.NET 體系結構中引入了異步頁面
      • 在 .NET Framework 2.0 之前的版本中,每個 ASP.NET 請求都需要一個執行緒,執行緒會直到該請求完成
      • 這會造成執行緒利用率低下,因為創建網頁通常依賴于資料庫查詢和 Web 服務呼叫,并且處理請求的執行緒必須等待,直到所有這些操作結束,
      • 后來使用異步頁面,處理請求的執行緒可以開始每個操作,然后回傳到 ASP.NET 執行緒池;當操作結束時,ASP.NET 執行緒池的另一個執行緒可以完成該請求
    • ISynchronizeInvoke 不太適合 ASP.NET 異步頁面體系結構,
      • 使用 ISynchronizeInvoke 模式開發的異步組件在 ASP.NET 頁面內無法正常作業,因為 ASP.NET 異步頁面不與單個執行緒關聯,
      • 需要設計出,無須將作業排入原來的執行緒佇列,異步頁面只需對未完成的操作進行計數 以確定頁面請求何時可以完成,
  • 經過精心設計, SynchronizationContext 取代了 ISynchronizeInvoke

3. 同步背景關系 的概念

ISynchronizeInvoke 滿足了兩點需求:

  1. 確定是否必須同步
  2. 使作業單元從一個執行緒列隊等候另一個執行緒,

設計 SynchronizationContext 是為了替代 ISynchronizeInvoke ,但完成設計后,它就不僅僅是一個替代品了,

  • 一方面SynchronizationContext 提供了一種方式,可以使作業單元列隊并列入背景關系
    • 請注意,作業單元是列入背景關系,而不是某個特定執行緒,
    • 這一區別非常重要,因為很多 SynchronizationContext 實作都不是基于單個特定執行緒的,
    • SynchronizationContext 不包含用來確定是否必須同步的機制,因為這是不可能的,
      • WPF 中的Dispatcher.Invoke是將委托列入背景關系,不等委托執行直接回傳
      • WinForm 中的txtUName.Invoke會啟動一個process,等到委托執行完畢后回傳
  • 另一方面,每個執行緒都有當前同步背景關系
    • 執行緒背景關系不一定唯一
    • 背景關系實體可以與多個其他執行緒共享
    • 執行緒可以更改其當前背景關系,但這樣的情況非常少見,
  • 第三個方面,保持了未完成操作的計數,
    • 這樣,就可以用于 ASP.NET 異步頁面和需要此類計數的任何其他主機,
    • 大多數情況下,捕獲到當前 SynchronizationContext 時,計數遞增
      • 捕獲到的 SynchronizationContext 用于將完成通知列隊到背景關系中時,計數遞減 void OperationCompleted()
  • 其他一些方面,這些對大多數編程人員來說并不那么重要
// SynchronizationContext API的重要方面
class SynchronizationContext
{

  // 將作業分配到背景關系中
  void Post(..); // (asynchronously 異步)

  void Send(..); // (synchronously 同步)

  // 跟蹤異步操作的數量,
  void OperationStarted();

  void OperationCompleted();

  // 每個執行緒都有一個Current Context,
  // 如果“Current”為null,則按照慣例,
  // 最開始的當前背景關系為 new SynchronizationContext(),
  static SynchronizationContext Current { get; }

  //設定當前同步背景關系
  static void SetSynchronizationContext(SynchronizationContext);
}

4. 同步背景關系 的實作

不同的框架和主機可以自行定義背景關系

通過了解這些不同的實作及其限制,可以清楚了解 SynchronizationContext 概念可以不可以實作的功能

4.1. WinForm 同步背景關系

位于:System.Windows.Forms.dll:System.Windows.Forms

WinForm

  • WinForm應用程式會創建并安裝一個 WindowsFormsSynchronizationContext
    • 作為創建 UI Control 的每個執行緒的當前背景關系
    • 一個 WinForm 應用程式對應一個同步背景關系
  • 這一 SynchronizationContext 使用 UI ControlInvoke 等方法(ISynchronizeInvoke派生出來的),該方法將委托傳遞給基礎 Win32 訊息回圈
  • WindowsFormsSynchronizationContext 的背景關系是一個單例的 UI 執行緒
  • WindowsFormsSynchronizationContext 列隊的所有委托一次一個地執行
    • 這個已排序的委托佇列,被一個特定 UI 執行緒執行完

4.2. Dispatcher 同步背景關系

位于:WindowsBase.dll:System.Windows.Threading

WPF

  • 委托按“Normal”優先級在 UI 執行緒的 Dispatcher 中列隊
  • 當一個執行緒通過呼叫 Dispatcher.Run 開啟 回圈調度器 時,將這個初始化完成的 同步背景關系 安裝到當前背景關系
  • DispatcherSynchronizationContext 的背景關系是一個單獨的 UI 執行緒,
  • 排隊到 DispatcherSynchronizationContext 的所有委托均由特定的UI執行緒一次一個按其排隊的順序執行
  • 當前實作為每個頂層視窗創建一個 DispatcherSynchronizationContext,即使它們都使用相同的基礎調度程式也是如此,

4.3. Default 同步背景關系

調度執行緒池執行緒的同步背景關系,

位于:mscorlib.dll:System.Threading

Default SynchronizationContext 是默認構造的 SynchronizationContext 物件,

  • 根據慣例,如果一個執行緒的當前 SynchronizationContext 為 null,那么它隱式具有一個Default SynchronizationContext
  • Default SynchronizationContext 將其異步委托列隊到 ThreadPool ,但在呼叫執行緒上直接執行其同步委托
  • 因此,Default SynchronizationContext涵蓋所有 ThreadPool 執行緒以及任何呼叫 Send 的執行緒,
  • 這個背景關系“借助”呼叫 Send執行緒們,將這些執行緒放入這個背景關系,直至委托執行完成
    • 從這種意義上講,默認背景關系可以包含行程中的所有執行緒
  • Default SynchronizationContext 應用于 執行緒池 執行緒,除非代碼由 ASP.NET 承載,
  • Default SynchronizationContext 還隱式應用于顯式子執行緒(Thread 類的實體),除非子執行緒設定自己的 SynchronizationContext

因此,UI 應用程式通常有兩個同步背景關系:

  • 包含 UI 執行緒的 UI SynchronizationContext
  • 包含 ThreadPool 執行緒的Default SynchronizationContext

4.4. 背景關系捕獲和執行

BackgroundWorker運行流程

  • 首先BackgroundWorker 捕獲使用呼叫 RunWorkerAsync 的執行緒的 同步背景關系
  • 然后,在Default SynchronizationContext中執行DoWork
  • 最后,在之前捕獲的背景關系中執行其 RunWorkerCompleted 事件

UI同步背景關系 中只有一個 BackgroundWorker ,因此 RunWorkerCompletedRunWorkerAsync 捕獲UI同步背景關系中執行(如下圖),

UI同步背景關系中的嵌套 BackgroundWorker

  • 嵌套: BackgroundWorker 從其 DoWork 處理程式啟動另一個 BackgroundWorker
    • 嵌套的 BackgroundWorker 不會捕獲 UI同步背景關系
  • DoWork執行緒池 執行緒使用 默認同步背景關系 執行,
    • 在這種情況下,嵌套的 RunWorkerAsync 將捕獲默認 SynchronizationContext
    • 因此它將由一個 執行緒池 執行緒而不是 UI執行緒 執行其 RunWorkerCompleted
    • 這樣會導致異步執行完后,后面的代碼就不在UI同步背景關系中執行了(如下圖),

默認情況下,控制臺應用程式Windows服務 中的所有執行緒都只有 Default SynchronizationContext,這會導致一些基于事件異步組件失敗(也就是沒有UI同步背景關系的特性)

  • 要解決這個問題,可以創建一個顯式子執行緒,然后將 UI同步背景關系 安裝在該執行緒上,這樣就可以為這些組件提供背景關系,
  • Nito.Async 庫的 ActionThread 類可用作通用同步背景關系實作,

4.5. AspNetSynchronizationContext

位于:System.Web.dll:System.Web [internal class]

ASP.NET

  • SynchronizationContext執行緒池執行緒執行頁面代碼安裝完成,
  • 當一個委托列入到捕獲AspNetSynchronizationContext 中時,它設定原始頁面的 identity 和 culture 到此執行緒,然后直接執行委托
    • 即使委托是通過呼叫 Post “異步”列入的,也會直接呼叫委托,

從概念上講, AspNetSynchronizationContext 的背景關系非常復雜,

  • 在異步頁面的生命周期中,該同步背景關系從來自 ASP.NET 執行緒池的一個執行緒開始,
    • 異步請求開始后,該背景關系不包含任何執行緒,
    • 異步請求結束時,執行緒池執行緒進入該背景關系并執行 處理完成的相關作業
  • 這可能是啟動請求的執行緒,但更可能是操作完成時處于空閑狀態的任何執行緒
  • 如果同一應用程式的多項操作同時完成, AspNetSynchronizationContext 確保一次只執行其中一項,它們可以在任意執行緒上執行,但該執行緒將具有原始頁面的 identity 和 culture,

一個常見的示例:

在異步網頁中使用 WebClient.DownloadDataAsync 將捕獲當前 SynchronizationContext ,之后在該背景關系中執行其 DownloadDataCompleted 事件,

  • 當頁面開始執行時,ASP.NET 會分配一個執行緒執行該頁面中的代碼,
  • 該頁面可能呼叫 DownloadDataAsync ,然后回傳;
    • ASP.NET 對未完成的異步操作進行計數,以便了解頁面處理是否已完成,
  • WebClient 物件下載所請求的資料后,它將在執行緒池執行緒上收到通知
    • 該執行緒將在捕獲的背景關系中引發 DownloadDataCompleted
  • 該背景關系將保持在相同的執行緒中,但會確保事件處理的運行使用正確的 identity 和 culture 運行

5. 同步上下實作類 的注意事項

  • SynchronizationContext 提供了一種途徑,可以在很多不同框架中撰寫組件

    • BackgroundWorkerWebClient 就是兩個在 WinFormWPFConsoleASP.NET Application中同樣應用自如的組件,
  • 在設計這類可重用組件時,必須注意幾點:

    • 同步背景關系的實作們不是平等可比的,

      • 這意味著沒有類似 ISynchronizeInvoke.InvokeRequired 的等效項
        • 此屬性確定在對如Concrol物件進行方法呼叫時,呼叫方是否必須通過 Invoke 進行呼叫(傳入委托),
        • 這樣的(Control)物件被系結到特定執行緒,并且不是執行緒安全的,
        • 如果要從其他執行緒呼叫物件的方法,則必須借助 Invoke 方法將對相應執行緒呼叫的委托列隊
      • 不過,這不是多大的缺點;代碼更為清晰,并且更容易驗證它是否始終在已知背景關系中執行,而不是試圖處理多個背景關系,
    • 不是所有 同步背景關系的實作 都可以保證委托執行順序或委托同步順序,

      • UI同步背景關系 滿足上述條件
      • ASP.NET同步背景關系 只提供同步
      • Default同步背景關系 不保證執行順序或同步順序
    • 同步背景關系實體執行緒之間沒有 1:1 的對應關系

      • WindowsFormsSynchronizationContext 確實 1:1 映射到一個執行緒(只要不呼叫 SynchronizationContext.CreateCopy
        • 任何其他實作都不是這樣
      • 一般而言,最好不要假設任何背景關系實體將在任何指定執行緒上運行
    • SynchronizationContext.Post 方法不一定是異步的

      • 大多數實作異步實作此方法,但 AspNetSynchronizationContext 是一個明顯的例外
      • 這可能會導致無法預料的重入問題

同步背景關系實作類的摘要

使用特定執行緒 執行委托 獨占 (一次執行一個委托) 有序 (委托按佇列順序執行) Send 可以直接呼叫委托 Post 可以直接呼叫委托
Winform 如果從UI執行緒呼叫 從不
WPF/Silverlight 如果從UI執行緒呼叫 從不
Default 不能 不能 不能 Always 從不
ASP.NET 不能 不能 Always Always

6. AsyncOperationManager 和 AsyncOperation

  • AsyncOperationManagerAsyncOperation 類是 SynchronizationContext 抽象類的輕型包裝
    • AsyncOperation的異步是使用抽象的同步背景關系進行封裝的
  • AsyncOperationManager 在第一次創建 AsyncOperation捕獲當前同步背景關系 ,如果當前同步背景關系為null,則使用 Default 同步背景關系
  • AsyncOperation 將委托異步發布到捕獲的 同步背景關系
  • 大多數基于事件的異步組件都在其實作中使用 AsyncOperationManagerAsyncOperation
    • 這些對于具有明確完成點的異步操作非常有效
      • 即異步操作從一個點開始,以另一個點的事件結束
    • 其他異步通知可能沒有明確的完成點;它們可能是一種訂閱型別,在一個點開始,然后無限期持續
      • 對于這些型別的操作,當觸發了被訂閱的事件,在事件處理中直接捕獲使用同步背景關系

新組件不應使用基于事件的異步模式

  • 使用基于Task的異步模式
    • 組件回傳 Task 和 Task 物件,而不是通過 同步背景關系 引發事件
    • 基于 Task 的 API 是 .NET 中異步編程的發展方向

7. 同步背景關系 的Library支持示例

  • BackgroundWorkerWebClient 這樣的簡單組件是隱式自帶的
    • 隱藏了對同步背景關系的捕獲和使用,
  • 很多 Libraries 以更可見的方式使用 同步背景關系
    • 通過使用 SynchronizationContext 公開 API,Libraries 不僅獲得了框架獨立性,而且為高級最終用戶提供了一個可擴展點,
  • ExecutionContext
    • 是與執行的邏輯執行緒相關的所有資訊提供單個容器, 這包括安全背景關系呼叫背景關系同步背景關系
    • 任何捕獲執行緒的 ExecutionContext 的系統都會捕獲當前 同步背景關系
    • 當恢復 ExecutionContext 時,通常也會恢復 同步背景關系

7.1. WCF

WCF 有兩個用于配置服務器和客戶端行為的特性:

  • ServiceBehaviorAttributeCallbackBehaviorAttribute
    • 這兩個特性都有一個 Boolean 屬性:UseSynchronizationContext
    • 此特性的默認值為 true,這表示在創建通信通道時捕獲當前 同步背景關系 ,這一捕獲的 同步背景關系 用于使約定方法列隊,
  • 服務器使用 Default 同步背景關系
  • 客戶端回呼使用相應的 UI 同步背景關系
  • 在需要重入時,這會導致問題,如客戶端呼叫的服務器方法回呼客戶端方法,在這類情況下,將 UseSynchronizationContext 設定為 false 可以禁止 WCF 自動使用 同步背景關系
    • 因為如果這時如果客戶端使用的是UI同步背景關系,可能造成不可預期的問題

7.2. Workflow Foundation (WF)

  • WorkflowInstance 類及其派生的 WorkflowApplication 類的SynchronizationContext 屬性

  • 如果承載行程創建自己擁有的 WorkflowInstance ,同步背景關系也許直接設定了

  • WorkflowInvoker.InvokeAsync 也使用 同步背景關系

    • 它捕獲當前 同步背景關系 并將其傳遞給其 internalWorkflowApplication
      • 該 同步背景關系 用于 Post 作業流完成事件以及作業流活動

7.3. Task Parallel Library (TPL)

TaskScheduler.FromCurrentSynchronizationContext

TPL 使用 Task 物件作為其作業單元并通過 TaskScheduler 執行,

  • 默認 TaskScheduler 的作用類似于 Defalut 同步背景關系 ,將 TaskThreadPool 中列隊,
  • TPL 佇列還提供了另一個 TaskScheduler ,將 Task 在 一個同步背景關系 中列隊
    • UI 進度條更新 可以在一個嵌套 Task 中完成,如下所示,

UI 進度條更新


private void button1_Click(object sender, EventArgs e)
{
  // 捕獲當前 SynchronizationContext 的 TaskScheduler.
  TaskScheduler taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
  // Start a new task (this uses the default TaskScheduler, 
  // so it will run on a ThreadPool thread).
  Task.Factory.StartNew(() =>
  {
    // We are running on a ThreadPool thread here.
    // Do some work.
    // Report progress to the UI.
    Task reportProgressTask = Task.Factory.StartNew(() =>
    {
      // We are running on the UI thread here.
      // Update the UI with our progress.
    },CancellationToken.None,
      TaskCreationOptions.None,
      taskScheduler);

    reportProgressTask.Wait();
    // Do more work.
  });
}

CancellationToken.Register

  • CancellationToken 類可用于任意型別的取消操作
  • 為了與現有取消操作形式集成,該類允許注冊委托以在請求取消時呼叫
    • 當取消委托被注冊后,同步背景關系就可以傳遞了
      • 當發起取消請求時, CancellationToken 將該委托列入 同步背景關系 佇列,然后才會進行執行

7.4. Reactive Extensions (Rx)

ObserveOnSubscribeOnSynchronizationContextScheduler

Rx 是一個庫,它將事件視為資料流

  • ObserveOn(context) 運算子通過一個 同步背景關系 將事件列隊
  • SubscribeOn(context) 運算子通過一個 同步背景關系 將對這些事件的訂閱 列隊
  • ObserveOn(context) 通常用于使用傳入事件更新 UI,SubscribeOn 用于從 UI 物件使用事件

Rx 還有它自己的作業單元列隊方法: IScheduler 介面,

  • Rx 包含 SynchronizationContextScheduler
    • 是一個將 Task 列入指定 同步背景關系 的 IScheduler 實作,
    • 構造方法: SynchronizationContextScheduler(SynchronizationContext context)

7.5. 異步編程 Async

awaitConfigureAwaitSwitchToProgress<T>

  • 默認情況下, 當前同步背景關系 在一個 await 關鍵字處被捕獲
  • 同步背景關系 用于在運行到 await關鍵字后時恢復
    • 也就是 await 關鍵字后面的執行代碼會被列入到 該同步背景關系 中執行
      • 僅當它不為 null 時,才捕獲當前 同步背景關系
      • 如果為 null ,則捕獲當前 TaskScheduler
private async void button1_Click(object sender, EventArgs e)
{
  // 當前 SynchronizationContext 被 await 在暗中捕獲
  var data = https://www.cnblogs.com/BigBrotherStone/p/await webClient.DownloadStringTaskAsync(uri);

  // 此時,已捕獲的SynchronizationContext用于恢復執行,
  // 因此我們可以自由更新UI物件,
}
  • ConfigureAwait 提供了一種途徑避免 SynchronizationContext 捕獲;

    • continueOnCapturedContext 引數傳遞 false 會阻止 await后的代碼,在 await 執行前的 同步背景關系 上執行
  • 同步背景關系實體還有一種擴展方法 SwitchTo

    • 使用該方法,任何 async 的方法 可以通過呼叫 SwitchTo 改變到一個不同的同步背景關系上,并 awaiting 結果

報告異步操作進展的通用模式:

  • IProgress<T> 介面及其實作 Progress<T>
    • 該類在構造時捕獲 當前同步背景關系
    • 并在中引發其 ProgressChanged 事件
    • 所以實體化時,需要在 UI同步背景關系 上執行

回傳 voidasync 方法

  • 在異步操作開始時遞增計數
  • 在異步操作結束后遞減計數

這一行為使回傳 voidasync 方法 類似于頂級異步操作,

8. 限制和功能

  • 了解 同步背景關系 對任何編程人員來說都是有益的
  • 現有跨框架組件使用它同步其事件
  • Libraries 可以將它公開以獲得更高的靈活性
  • 技術精湛的編程人員了解 同步背景關系 限制和功能后,可以更好地撰寫和利用這些類

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/77411.html

標籤:C#

上一篇:C# 7

下一篇:ThreadPool(執行緒池)介紹

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more