3

.NETでのタスクのブロックについてどのくらい心配する必要がありますか?つまり、.NETタスクスケジューラは、スレッドプール内のスレッドのブロックとオーバーサブスクリプションをどのように処理しますか?

たとえば、タスクにIOがある場合、常にLongRunningヒントを使用して作成する必要がありますか?または、タスクスケジューラのヒューリスティックはそれをより適切に処理しますか?C ++にはOversubscribe完全に機能するヒントがありますが、.NETで同等のものは見つかりませんでした。

4

3 に答える 3

2

最もパフォーマンスの高いコードが必要な場合は、これについて心配する必要があります。

これを処理する最善の方法は、.Net 4.5 の「await」スタイルの I/Oを使用することです。

.Net 4.5 を持っていない場合は、古いスタイルの I/Oを使用する必要があります(これも同様に機能しますが、使いにくいです)。

これらの記事で説明されているノンブロッキング I/O は、複数のスレッドで I/O を実行するための最良の方法です。

I/O を使用していない場合でも、これらの記事から多くのことを学ぶことができます。

于 2013-02-26T09:18:22.163 に答える
2

ThreadPool は、そのスレッドの 1 つがいつブロックされるかを検出します。これは、別のスレッドをプールに追加するためのヒントです。そのため、多くのブロックを行っても、ThreadPool が CPU コアをビジー状態に保とうとするため、パフォーマンスはおそらくそれほど悪くはありません。

ただし、ブロックされたスレッドが多数あると、メモリ消費量が増加し、コンテキスト スイッチが増える可能性があるため、パフォーマンスの問題が発生する可能性があります。

また、この動作により、IO のパフォーマンスが低下する可能性があります。回転ディスク (HDD) では、同時に多くのファイルにアクセスすると大量のシークが発生し、パフォーマンスに大きな影響を与える可能性があります。

于 2013-02-26T18:21:05.603 に答える
1

LongRunningスレッドプール スレッドを使用しないように TPLに通知します。これは、スレッドプール以外のスレッドを作成して要求を実行します (例: new Thread(...))。これは、IO に対して行うべきことではありません。非同期 IO を使用する必要があります。例えば:

using(var response = (HttpWebResponse)await WebRequest.Create(url).GetResponseAsync())
    return response.StatusCode == HttpStatusCode.OK;

これにより、可能な限り、IO スレッドプールを使用するオーバーラップ IO が使用されます。

従来の APM API でタスクを使用する場合は、FromAsync を使用できます。

Task<int> bytesRead = Task<int>.Factory.FromAsync( 
    stream.BeginRead, stream.EndRead, buffer, 0, buffer.Length, null);
await bytesRead;

従来のイベント非同期 API を処理する必要がある場合は、TaskCompletionSource を使用できます。

TaskCompletionSource<string[]> tcs = new TaskCompletionSource<string[]>();
WebClient[] webClients = new WebClient[urls.Length];
object m_lock = new object();
int count = 0;
List<string> results = new List<string>();

for (int i = 0; i < urls.Length; i++)
{
    webClients[i] = new WebClient();

    // Specify the callback for the DownloadStringCompleted 
    // event that will be raised by this WebClient instance.
    webClients[i].DownloadStringCompleted += (obj, args) =>
    {
        // Argument validation and exception handling omitted for brevity. 

        // Split the string into an array of words, 
        // then count the number of elements that match 
        // the search term. 
        string[] words = args.Result.Split(' ');
        string NAME = name.ToUpper();
        int nameCount = (from word in words.AsParallel()
                         where word.ToUpper().Contains(NAME)
                         select word)
                        .Count();

        // Associate the results with the url, and add new string to the array that  
        // the underlying Task object will return in its Result property.
        results.Add(String.Format("{0} has {1} instances of {2}", args.UserState, nameCount, name));

        // If this is the last async operation to complete, 
        // then set the Result property on the underlying Task. 
        lock (m_lock)
        {
            count++;
            if (count == urls.Length)
            {
                tcs.TrySetResult(results.ToArray());
            }
        }
    };

    // Call DownloadStringAsync for each URL.
    Uri address = null;
    address = new Uri(urls[i]);
    webClients[i].DownloadStringAsync(address, address);

} // end for 

await tcs.Task;
于 2013-02-26T18:26:22.340 に答える