生成器、异步、阻塞

sdfgrtyu 2018-12-10 02:57:25
 public IEnumerable<int> Generate(int amount) {
for(int i = 0; i < amount; i++)
{
Thread.Sleep(TimeSpan.FromSeconds(2));
yield return i;
}
}


如上,这个方法不能改变,方法需要时间来生成每个数字(2秒),所以主线程将在这里阻塞5 * 2 = 10秒,
应该如何调用这个方法?
...全文
171 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
hez2010 2018-12-20
  • 打赏
  • 举报
回复

var iter = Generate(5).GetEnumerator();
while (iter.MoveNext())
{
Console.WriteLine(iter.Current);
}
  • 打赏
  • 举报
回复
本末倒置地逻辑,本身就是只会阻塞、不会别的设计。所以先要改变自己的思维方式,否则没有什么前途。
  • 打赏
  • 举报
回复
当你写迭代器
public IEnumerable<int> Generate(int amount) {
            for(int i = 0; i < amount; i++)
            {
                yield return i;
            }
        }
的时候,这个Generate 方法本身就是异步的,它仅仅是被动返回一个 MoveNext 动作结果而已,你调用它的方法间隔多少时间调用一次这个方法的 MoveNext 机制,就会自然而然地间隔长时间。 这就好像一个人本身是瞎子,却来责怪房间里没有安装电灯。完全是本末倒置的。 故意颠倒黑白,把程序设计的源头驱动逻辑给颠倒了,明明是调用 Generate(.....).MoveNext 的客户代码不按照间隔时间调用它,却说什么是这个迭代器不去主动调用自己的宿主代码。
xiaohe96 2018-12-20
  • 打赏
  • 举报
回复
Generate(5).ToArray(); 或者 foreach(var data in Generate(5)) 不想卡死的话就异步调用了
threenewbee 2018-12-10
  • 打赏
  • 举报
回复
放在线程里调用了 new ThreadStart(new Action(() => foreach (var item in Generate()) ... ));
stherix 2018-12-10
  • 打赏
  • 举报
回复
引用 8 楼 sdfgrtyu 的回复:
这没法知道程序完没完成啊?在Task.Factory.StartNew前面加awiat,可是返回的是void啊
只要await返回就代表已经结束了
sdfgrtyu 2018-12-10
  • 打赏
  • 举报
回复
引用 7 楼 stherix 的回复:
[quote=引用 5 楼 stherix 的回复:]
[quote=引用 3 楼 sdfgrtyu 的回复:]
[quote=引用 1 楼 stherix 的回复:]
Generate(5).ToArray();
或者
foreach(var data in Generate(5))

不想卡死的话就异步调用了

问的就是这个啊[/quote]

你用个异步方法来处理不就行了吗
void async Dothis() {处理这些数字} 或者List<int> async GetAmount(){ return Generate(5); }
在主线程里await Dothis(); 或者var result = await GetAmount();[/quote]
那就
public void Doit() { foreach(var Amount in Generate(5)) { DoWith(Amount ); } }

主程序
Task.Factory.StartNew(Doit);[/quote]
这没法知道程序完没完成啊?在Task.Factory.StartNew前面加awiat,可是返回的是void啊
stherix 2018-12-10
  • 打赏
  • 举报
回复
引用 5 楼 stherix 的回复:
[quote=引用 3 楼 sdfgrtyu 的回复:] [quote=引用 1 楼 stherix 的回复:] Generate(5).ToArray(); 或者 foreach(var data in Generate(5)) 不想卡死的话就异步调用了
问的就是这个啊[/quote] 你用个异步方法来处理不就行了吗 void async Dothis() {处理这些数字} 或者List<int> async GetAmount(){ return Generate(5); } 在主线程里await Dothis(); 或者var result = await GetAmount();[/quote] 那就 public void Doit() { foreach(var Amount in Generate(5)) { DoWith(Amount ); } } 主程序 Task.Factory.StartNew(Doit);
sdfgrtyu 2018-12-10
  • 打赏
  • 举报
回复
引用 5 楼 stherix 的回复:
[quote=引用 3 楼 sdfgrtyu 的回复:]
[quote=引用 1 楼 stherix 的回复:]
Generate(5).ToArray();
或者
foreach(var data in Generate(5))

不想卡死的话就异步调用了

问的就是这个啊[/quote]

你用个异步方法来处理不就行了吗
void async Dothis() {处理这些数字} 或者List<int> async GetAmount(){ return Generate(5); }
在主线程里await Dothis(); 或者var result = await GetAmount();[/quote]
可是本来是2秒钟一个,现在这种写法需要阻塞10秒钟了啊
stherix 2018-12-10
  • 打赏
  • 举报
回复
引用 3 楼 sdfgrtyu 的回复:
[quote=引用 1 楼 stherix 的回复:] Generate(5).ToArray(); 或者 foreach(var data in Generate(5)) 不想卡死的话就异步调用了
问的就是这个啊[/quote] 你用个异步方法来处理不就行了吗 void async Dothis() {处理这些数字} 或者List<int> async GetAmount(){ return Generate(5); } 在主线程里await Dothis(); 或者var result = await GetAmount();
sdfgrtyu 2018-12-10
  • 打赏
  • 举报
回复
引用 2 楼 angel6709 的回复:
这个在for循环时会被阻塞

问的就是这个啊
sdfgrtyu 2018-12-10
  • 打赏
  • 举报
回复
引用 1 楼 stherix 的回复:
Generate(5).ToArray();
或者
foreach(var data in Generate(5))

不想卡死的话就异步调用了

问的就是这个啊
angel6709 2018-12-10
  • 打赏
  • 举报
回复
这个在for循环时会被阻塞
stherix 2018-12-10
  • 打赏
  • 举报
回复
Generate(5).ToArray(); 或者 foreach(var data in Generate(5)) 不想卡死的话就异步调用了

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧