C# 异步/等待竞争条件
我相信我有下面的比赛条件。我正在手动构造一个HttpResponseMessage,其中JSON输出异步流。问题似乎出在柜台i上。我想在列表中第一次写入后的任何元素之前添加一个逗号 在列表的开头,有时我看到的第一个write3之后的前几条记录将没有前面的逗号。数字不一致,有时工作正常。我在本地机器上没有看到它,但在部署了更强大硬件的环境中,它是存在的C# 异步/等待竞争条件,c#,asynchronous,stream,async-await,task-parallel-library,C#,Asynchronous,Stream,Async Await,Task Parallel Library,我相信我有下面的比赛条件。我正在手动构造一个HttpResponseMessage,其中JSON输出异步流。问题似乎出在柜台i上。我想在列表中第一次写入后的任何元素之前添加一个逗号 在列表的开头,有时我看到的第一个write3之后的前几条记录将没有前面的逗号。数字不一致,有时工作正常。我在本地机器上没有看到它,但在部署了更强大硬件的环境中,它是存在的 var LastUpdate = JsonConvert.SerializeObject(dt); var pre = $"{{ \"LastUp
var LastUpdate = JsonConvert.SerializeObject(dt);
var pre = $"{{ \"LastUpdate\": {LastUpdate}, \"List\":[";
var post = "]}";
HttpResponseMessage response = Request.CreateResponse();
response.Content = new PushStreamContent(
async (stream, http, context) =>
{
try
{
int i = 0;
var buffer = Encoding.UTF8.GetBytes(pre);
await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);
var query = getQuery(id);
await query
.ForEachAsync(async entity =>
{
var student = MapRecord(entity);
if (student != null)
{
var json = JsonConvert.SerializeObject(student);
buffer = Encoding.UTF8.GetBytes(((i > 0) ? ", " : "") + json);
await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);
i++;
}
}, cancellationToken).ConfigureAwait(false);
buffer = Encoding.UTF8.GetBytes(post);
await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);
}
如果你正在使用Thank@juharr,那么是的,你有一个比赛条件
该方法的签名为:
public static Task ForEachAsync<T>(
this IQueryable<T> source,
Action<T> action
)
如果你正在使用Thank@juharr,那么是的,你有一个比赛条件
该方法的签名为:
public static Task ForEachAsync<T>(
this IQueryable<T> source,
Action<T> action
)
如果您主要关心的是i计数器,那么可以使用联锁的.Increment来安全地执行Increment i。这将导致少量的同步性能争用,但您可以通过这种方式一致地更新i 例如:
Interlocked.Increment(ref i);
如果您主要关心的是i计数器,那么可以使用联锁的.Increment来安全地执行Increment i。这将导致少量的同步性能争用,但您可以通过这种方式一致地更新i 例如:
Interlocked.Increment(ref i);
ForEachAsync是如何声明的?@YuvalItzchakov可能是OP在使用ForEachAsync是如何声明的?@YuvalItzchakov可能是OP在使用ForEachAsync来防止数据库级别的阻塞此查询返回约100万行,是否有其他关于同步计数器的建议?如果是100万行,foreach可能不是最好的主意。是否有任何原因导致您实际手动执行序列化?如果这是不可避免的,我建议只使用同步委托并使用stream.Write而不是stream.WriteAsync。或者更好的方法是,为EF创建一个pull请求,并在ForEachAsync中添加一个调用异步委托的选项:引入整个结果集,映射和序列化内存异常命中。手动构造并不理想,但允许一次传输少量数据。使用这种方法,他们的资源占用非常少。也许更明智的想法是使用JsonTextWriter。请参阅问题。使用foreachasync防止数据库级阻塞此查询返回约100万行,是否还有其他关于同步计数器的建议?如果是100万行,foreach可能不是最好的主意。是否有任何原因导致您实际手动执行序列化?如果这是不可避免的,我建议只使用同步委托并使用stream.Write而不是stream.WriteAsync。或者更好的方法是,为EF创建一个pull请求,并在ForEachAsync中添加一个调用异步委托的选项:引入整个结果集,映射和序列化内存异常命中。手动构造并不理想,但允许一次传输少量数据。使用这种方法,他们的资源占用非常少。也许更明智的想法是使用JsonTextWriter。见问题。