8

私はマルチスレッドに少し慣れていないので、過去にそれをいじっただけです。しかし、メインスレッドにバイト配列のリストを設定し、別のスレッドで新しいバイト配列を作成するときにそのリストに追加できるかどうかは気になります。また、バイト配列への解析に使用されるフォームのリストを通過するfor-eachループを使用します。したがって、基本的に擬似コードは次のようになります...

reports = new List();

foreach (form in forms)  
{  
    newReport = new Thread(ParseForm(form));  
    reports.Add(newReport);  

}  

void ParseForm(form)  
{  
    newArray = new byte[];  
    newArray = Convert.ToBytes(form);  
    return newArray;  
}

うまくいけば、上記の擬似コードはある程度意味があります。誰かがこれが可能かどうか教えてくれて、良い例の方向に私を向けることができれば、私は実際のコードを理解できると確信しています。

4

4 に答える 4

4

複数のスレッドからコレクションにアクセスする必要がある場合は、同期を使用するSynchronizedCollectionか、.NETバージョンが3.0以降の場合はを使用する必要があります。

コレクションをスレッドにアクセスできるようにする1つの方法は次のとおりです。

SynchronizedCollection reports = new SynchronizedCollection();

foreach (form in forms) {  
    var reportThread = new Thread(() => ParseForm(form, reports));
    reportThread.Start();
}

void ParseForm(Form form, SynchronizedCollection reports) {  
    newArray = new byte[];  
    newArray = Convert.ToBytes(form);  
    reports.Add(newArray);
}

.NET 4以降を使用している場合は、System.Threading.Tasks名前空間のさまざまなクラスによって、スレッドを手動で管理するよりもはるかに優れた代替手段が提供されます。スレッドの実装を決定する前に、この代替案を検討することを検討してください。

于 2012-05-16T14:17:04.047 に答える
4

.Net 3.5であることに気付く前に、.Net4で参照してください。

リスト内で順序が必要ない場合、簡単な「修正」は、リストの代わりにConcurrentBag<T>クラスを使用することです。さらに注文が必要な場合は、ConcurrentQueue<T>コレクションもあります。

もっとカスタムが必要な場合は、BlockingCollection<T>を使用して独自のブロッキングコレクションを実装できます。 これがこのトピックに関する良い記事です。

Parallel.Foreachを使用して、明示的なスレッドの作成を回避することもできます。

private void ParseForms()
{
    var reports = new ConcurrentBag<byte[]>();
    Parallel.ForEach(forms, (form) =>
                                {
                                    reports.Add(ParseForm(form));
                                });

}

private byte[] ParseForm(form)  
{  
    newArray = new byte[];  
    newArray = Convert.ToBytes(form);  
    return newArray;  
}
于 2012-05-16T14:15:05.490 に答える
0

列挙ファイルが同じファイルを複数回返すのはなぜですか?

それをチェックしてください。それは私があなたがやりたいことを正確に考えていることを示しています。

メインスレッドにリストを作成し、別のスレッドからリストに追加します。あなたが必要とする

using System.Threading.Tasks

-

Files.Clear(); //List<string> 

Task.Factory.StartNew( () =>
{
      this.BeginInvoke( new Action(() =>
         {
            Files.Add("Hi");
         }));
 });
于 2012-05-16T14:12:07.220 に答える
0

以下は、C#4.0にアクセスできないため、今すぐ作成した単純なブロッキングコレクション(キューとしてのみ)です。4.0の同時コレクションよりも効率が低い可能性がありますが、十分に機能するはずです。すべてのQueueメソッドを再実装するのではなく、エンキュー、デキュー、およびピークするだけです。他の人が必要で、それらがどのように実装されるかわからない場合は、コメントでそれを述べてください。

動作するブロッキングコレクションを取得したら、プロデューサースレッドからコレクションに追加し、コンシューマースレッドを使用してコレクションから削除できます。

public class MyBlockingQueue<T>
{
    private Queue<T> queue = new Queue<T>();
    private AutoResetEvent signal = new AutoResetEvent(false);
    private object padLock = new object();

    public void Enqueue(T item)
    {
        lock (padLock)
        {
            queue.Enqueue(item);
            signal.Set();
        }
    }

    public T Peek()
    {
        lock (padLock)
        {
            while (queue.Count < 1)
            {
                signal.WaitOne();
            }

            return queue.Peek();
        }
    }

    public T Dequeue()
    {
        lock (padLock)
        {
            while (queue.Count < 1)
            {
                signal.WaitOne();
            }

            return queue.Dequeue();
        }
    }
}
于 2012-05-16T14:49:03.883 に答える