簡體   English   中英

c#4.5-如果主要進行數據庫插入的TCP Server應該在Task上啟動每個客戶端

[英]c# 4.5 - Should a TCP Server, mainly doing database inserts, start each client on a Task

我的理解是異步等待用於IO(網絡,數據庫等),並行任務用於cpu。

注意:為了使本文簡潔,此代碼有些苛刻。

我有一個用以下代碼在c#中創建的Windows服務

while (true)
{
    var socket = await tcpListener.AcceptSocketAsync();
    if (socket == null) { break; }

    var client = new RemoteClient(socket);
    Task.Run(() => client.ProcessMessage());
}

在RemoteClient類中,ProcessMessage方法執行此操作

byte[] buffer = new byte[4096];
rawMessage = string.Empty;
while (true)
{
    Array.Clear(buffer, 0, buffer.Length);
    int bytesRead = await networkStream.ReadAsync(buffer, 0, buffer.Length);
    rawMessage += (System.Text.Encoding.ASCII.GetString(buffer).Replace("\0", string.Empty));

    if (bytesRead == 0 || buffer[buffer.Length - 1] == 0)
    {
        StoreMessage();
        return;
    }
}

因此,我的I / O工作是異步進行的。 但是我的關心和問題是使用Task.Run開始工作,我是否還在創建塊?

我試圖建立一個TCP連接並盡快釋放它,以便擴展到大量連接。

我覺得我在這里混合范例。

謝謝

我的理解是異步等待用於IO(網絡,數據庫等),並行任務用於cpu。

我會說理解是不正確的。 async / await用於任何異步操作,無論是I / O還是CPU綁定。

…我的擔心和我的問題是使用Task.Run開始工作,我是否還在創建塊?

“一塊”? 您認為您將創建哪種類型的障礙?


就個人而言,我不會以這種方式編寫代碼。 accept操作將在線程池線程中(或在同一線程中同步)完成,即IOCP線程池中的一個。 為該線程上的連接設置一些初始條件,然后從那里啟動I / O是完全可以的。 沒有理由將工作放在另一個線程上。

所以我編寫代碼的方式是這樣的:

async Task ProcessMessage()
{
    byte[] buffer = new byte[4096];
    rawMessage = string.Empty;
    while (true)
    {
        Array.Clear(buffer, 0, buffer.Length);
        int bytesRead = await networkStream.ReadAsync(buffer, 0, buffer.Length);
        rawMessage += (System.Text.Encoding.ASCII.GetString(buffer).Replace("\0", string.Empty));

        if (bytesRead == 0 || buffer[buffer.Length - 1] == 0)
        {
            StoreMessage();
            return;
        }
    }
}

然后為您服務:

while (true)
{
    var socket = await tcpListener.AcceptSocketAsync();
    if (socket == null) { break; }

    var client = new RemoteClient(socket);
    var _ = client.ProcessMessage();
}

筆記:

  • 僅提供_變量以防止編譯器警告您有關被忽略的,未等待的異步返回)
  • 由於您忽略返回的Task對象,因此不會收到引發的異常。 因此,您應該向ProcessMessage()方法本身添加適當的異常處理。
  • 我同意評論者shr關於清理的意見。 您沒有提供完整的代碼示例,因此我們不知道StoreMessage()方法的作用。 但是,大概/希望您在其中的邏輯正確,正常地關閉了連接並關閉了套接字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM