私はいくつかの文書を含んでいるリストを持っています。今、リストにはゆっくりとデータが取り込まれています。私がしたいのは、リストのサイズが20に達したときです。メインメソッドを停止することなく、これらの文字列を非同期的に出力する別の関数を呼び出したいとします。検索多くの後、私はこれは私が、私はなぜ唯一の最後のデータ、すなわち渡され、印刷されて把握することはできません異なるデータで同じ非同期タスクを複数呼び出すC#
List contents when calling: 0
List contents when calling: 20
List contents when calling: 40
List contents when calling: 60
1 80
3 80
0 80
2 80
4 80
80 80 80 80 81 82 83 84 85 86 87 88 89
81 82 83 84 85 86 87 88 89
81 82 83 84 85 86 87 88 89
81 82 83 84 85 86 87 88 89
80 81 82 83 84 85 86 87 88 89
Done DoStuff
Done Main
出力として取得していますものです
public void DoStuff()
{
Class1 p = new Class1();
List<string> list = new List<string> { };
var TList = new List<Task>();
int i = 0;
while (i < 90)
{
list.Add(i.ToString());
if (list.Count == 20)
{
Console.WriteLine("List contents when calling: " + list[0]);
TList.Add(Task.Run(() => publishDoc(list)));
list.Clear();
}
i++;
}
if (list.Count != 0)
{
TList.Add(Task.Run(() => publishDoc(list)));
}
Task.WhenAll(TList).Wait();
Console.WriteLine("Done DoStuff");
}
public async Task publishDoc(List<string> docs)
{
Console.WriteLine(iter++ + " " + docs[0]);
await Task.Run(() => Thread.Sleep(1000));
foreach (var val in docs)
{
Console.Write(val + " ");
}
Console.WriteLine();
}
このコードを一緒に入れて管理しています渡されたリストが上書きされる理由私はこの
public void DoStuff()
{
Program2 p = new Program2();
List<string> list = new List<string> { };
int i = 0;
while (i < 90)
{
list.Add(i.ToString());
if (list.Count == 20)
{
Console.WriteLine("List contents when calling: " + list[0]);
var tasks = publishDoc(list);
if (tasks.Result == "Done")
{
Console.WriteLine("Done " + list[0]);
}
list.Clear();
}
i++;
}
if (list.Count != 0)
{
var tasks = publishDoc(list);
if (tasks.Result == "Done")
{
Console.WriteLine("Done " + list[0]);
}
}
Console.WriteLine("Done DoStuff");
}
public async Task<string> publishDoc(List<string> docs)
{
Console.WriteLine(iter++ + " " + docs[0]);
foreach (var val in docs)
{
Console.Write(val + " ");
}
Console.WriteLine();
return await Task.Run(() => "Done");
}
をすれば は、今私は、この出力
List contents when calling: 0
0 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Done 0
List contents when calling: 20
1 20
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
Done 20
List contents when calling: 40
2 40
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
Done 40
List contents when calling: 60
3 60
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
Done 60
4 80
80 81 82 83 84 85 86 87 88 89
Done 80
Done DoStuff
Done Main
これは正しい出力を与えているが、私はしたくないどの同期それをやっている取得します。助けてくれてありがとう。
1. 2番目のアプローチを忘れてしまいます。 2. 'list.Clear();' - これは何をすると思いますか?タスクの参照を渡したリストをクリアします。 – Fildor
あなたの最初のリスティングはほぼ正しいですが、同じリストインスタンスへの参照を渡していました。 'list.Clear();の代わりに' list = new List(); ' –
を使用するこれはC#でスレッドを使うことでよくある問題です。あなたのメインタスクがwhileメソッドを通って歩いていると仮定しましょう.Task.Run()のラムダは80を取得します。<。スレッドを使用する場合は、変数を直ちに取得するParameterizedThreadStartを使用できます。残念ながら私はどのようにタスクでその問題を解決するか分かりません。 – Noren