Я использую .NET 4.0 и имеют следующий код:Task.FromAsync и две нити
var stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize,
FileOptions.Asynchronous | FileOptions.SequentialScan);
var buffer = new byte[bufferSize];
Debug.Assert(stream.IsAsync, "stream.IsAsync");
var ia = stream.BeginRead(buffer, 0, buffer.Length, t =>
{
var ms = new MemoryStream(buffer);
using (TextReader rdr = new StreamReader(ms, Encoding.ASCII))
{
for (uint iEpoch = 0; item < FileHeader.NUMBER_OF_ITEMS; item++)
{
dataList.Add(epochData);
}
}
}, null);
return Task<int>.Factory.FromAsync(ia, t =>
{
var st = stream;
var bytes1 = st.EndRead(t);
var a = EpochDataList.Count;
var b = FileHeader.NUMBER_OF_EPOCHS;
Debug.Assert(a == b);
st.Dispose();
return bytes1;
});
И это, кажется, что есть условия гонки между исполнением асинхронным обратного вызова и конечной функции метод лямбда (утверждают, является повышение). Но, по словам msdn это явно указано, что конечный метод должен быть выполнение после асинхронного обратного вызова завершен:
Создает задачу, которая выполняет функцию методы конечной, когда указанный IAsyncResult завершается.
Правильно ли я, что я запутанный факт завершения операции ввода-вывод, который запускающий метод конечного и факт завершения асинхронного обратного вызова, поэтому оба они потенциально могут выполнять в то же время?
Между тем этот код прекрасно работает:
return Task<int>.Factory.FromAsync(stream.BeginRead, (ai) =>
{
var ms = new MemoryStream(buffer);
using (TextReader rdr = new StreamReader(ms, Encoding.ASCII))
{
using (TextReader rdr = new StreamReader(ms, Encoding.ASCII))
{
for (uint iEpoch = 0; item < FileHeader.NUMBER_OF_ITEMS; item++)
{
dataList.Add(epochData);
}
}
}
stream.Dispose();
return stream.EndRead(ai);
}, buffer, 0, buffer.Length, null);
Кроме того, я должен упомянуть, что возвращается задача используется в продолжении.
Заранее спасибо.
Вы используете поток неправильно. 'EndRead' сообщает вам, сколько байтов было * на самом деле * прочитано.Я бы настоятельно предположил, что вам нужно вызвать этот метод * до *, вы можете что-либо сделать с помощью 'buffer', так как он сообщает вам, сколько байтов в' buffer' действительно действительно. –