簡體   English   中英

如何使用DataReader的Task Parallel庫

[英]How to work with Task Parallel library with DataReader

我經常用數據填充數據閱讀器並以這種方式填充UI

using (SqlConnection conn = new SqlConnection("myConnString"))
using (SqlCommand comm = new SqlCommand("Select * from employee where salary<5000", conn))
{
    conn.Open();

    SqlDataReader reader = comm.ExecuteReader();

    if (reader.HasRows)
    {
        while (reader.Read())
        {
            // here i populate my employee class
        }
    }
    // here i update UI
}

我正在尋找使用DataReader的任務並行庫並找到一段代碼。 它看起來不錯,但對我來說目標不是很明確。 所以這是我得到的代碼。

public IEnumerable<MyDataClass> ReadData()
{
using (SqlConnection conn = new SqlConnection("myConnString"))
using (SqlCommand comm = new SqlCommand("myQuery", conn))
{
    conn.Open();

    SqlDataReader reader = comm.ExecuteReader();

    if (reader.HasRows)
    {
        while (reader.Read())
        {
            yield return new MyDataClass(... data from reader ...);
        }
    }
}
}

打電話給

Parallel.ForEach(this.ReadData(), data =>
{
// Use the data here...
});

要么

this.ReadData().AsParallel().ForAll(data => 
{
// Use the data here...
});

我怎樣才能從ForAll獲取數據。

誰能幫助我理解的代碼片段,我如何工作的,以及如何從獲得的ForAll數據和如何填充從我的ForAll UI。

另一個問題是我怎么知道哪個類是線程安全的。 什么是線程安全的意思。 一個人說datareader不是線程安全的。 他怎么知道的。

一個人應該使用任務並行庫的另一個問題。 請指導。 謝謝

您可以在MSDN文檔中找到有關.NET基類庫中每種類型的線程安全性的信息。 大多數類型不是線程安全的。 例如, SqlDataReader 不是線程安全的,因為它適用於與數據庫的單個連接。

但是, Parallel.ForEach是一個非常清晰的構造。 你不能真正迭代同時使用多個線程的IEnumerable ,而Parallel.ForEach不會這樣做。 雖然它會旋轉多個線程並且那些多個線程會在給定的IEnumerable上進行迭代,但Parallel.ForEach確保當時只有一個線程迭代可枚舉的IEnumerator 它假設處理元素比從枚舉中獲取項目花費更多時間。 迭代可枚舉是一個順序操作。

這意味着即使底層數據源和SqlReader的使用不是線程安全的,您仍然可以使用Parallel.ForEach處理項目。 遺憾的是,MSDN文檔對此並不十分明確,但必須如此,因為從GetEnumerator()方法返回的IEnumerator實例從不是線程安全的。

當然,你必須確保給定的Action<T>是線程安全的。

您可以使用以下程序查看此行為:

public static IEnumerable<int> GetNumbers()
{
    for (int i = 0; i < 140; i++)
    {
        Console.WriteLine(
            "                          Enumerating " + 
            i + " at thread " +
            Thread.CurrentThread.ManagedThreadId);

        yield return i;
    }
}

static void Main(string[] args)
{
    Console.ReadLine();

    Parallel.ForEach(GetNumbers(), number =>
    {
        Console.WriteLine("Processing " + number + 
            " at thread " +
            Thread.CurrentThread.ManagedThreadId);

        Thread.Sleep(1);
    });
}

暫無
暫無

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

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