C# 如何避免在“下一步”完成之前调用onComplete?
假设我有一个数据服务类,它一批一批地获取数据,并将数据块发送给订阅者C# 如何避免在“下一步”完成之前调用onComplete?,c#,system.reactive,reactive-programming,C#,System.reactive,Reactive Programming,假设我有一个数据服务类,它一批一批地获取数据,并将数据块发送给订阅者 public class DataService { public IObservable<IList<T>> QuerySegmentedObservable<T>(string tableName) where T : TableEntity, new(){ return Observable.Create<IList<T>>(async
public class DataService {
public IObservable<IList<T>> QuerySegmentedObservable<T>(string tableName) where T : TableEntity, new(){
return Observable.Create<IList<T>>(async (observer, token) =>{
TableContinuationToken continuationToken = null;
do{
var currentSegment = CallData();
observer.OnNext(currentSegment.Results);
continuationToken = currentSegment.ContinuationToken;
} while (continuationToken != null);
observer.OnCompleted();
}
}
}
公共类数据服务{
public IObservable QuerySegmentedObservable(字符串tableName),其中T:TableEntity,new(){
返回可观察的。创建(异步(观察者,令牌)=>{
TableContinuationToken continuationToken=null;
做{
var currentSegment=CallData();
observer.OnNext(currentSegment.Results);
continuationToken=currentSegment.continuationToken;
}while(continuationToken!=null);
observer.OnCompleted();
}
}
}
我同意如下所示
public async Task<bool> MyMethod()
{
var tcs = new TaskCompletionSource<bool>();
var observable = _dataService.QuerySegmentedObservable<TSource>(_sourceTableName);
var dataCount = 0;
_databaseService.OpenConnection();
observable.Subscribe(async data =>
{
await _databaseService.DoSomething(data);
dataCount += data.Count;
Console.WriteLine($"Processing - {dataCount}");
},
err =>
{
Console.WriteLine($"Error - {err.Message}");
tcs.SetResult(false);
},
() =>
{
_databaseService.CloseConnection();
Console.WriteLine($"Finished");
tcs.SetResult(true);
}
);
return await tcs.Task;
}
公共异步任务MyMethod()
{
var tcs=new TaskCompletionSource();
var observable=\u dataService.QuerySegmentedObservable(\u sourceTableName);
var-dataCount=0;
_databaseService.OpenConnection();
可观察。订阅(异步数据=>
{
wait_databaseService.DoSomething(数据);
dataCount+=data.Count;
WriteLine($“Processing-{dataCount}”);
},
错误=>
{
WriteLine($“Error-{err.Message}”);
tcs.SetResult(假);
},
() =>
{
_databaseService.CloseConnection();
Console.WriteLine($“已完成”);
tcs.SetResult(真);
}
);
返回等待任务;
}
问题是OnComplete()是在最后一个OnNext()完成之前调用的
有没有办法修复它?谢谢。Rx在运营商内部支持异步/等待。您在订阅中使用它。因此(希望)您可以将代码更改为如下内容:
public async Task<bool> MyMethod()
{
var tcs = new TaskCompletionSource<bool>();
_databaseService.OpenConnection();
var dataCount = 0;
_dataService.QuerySegmentedObservable<TSource>(_sourceTableName)
.SelectMany(async data =>
{
await _databaseService.DoSomething(data);
return data;
})
//.Finally(() => _databaseService.CloseConnection()) //This would be called on OnComplete and OnError, just like try-finally
.Subscribe(data =>
{
dataCount += data.Count;
Console.WriteLine($"Processing - {dataCount}");
},
err =>
{
Console.WriteLine($"Error - {err.Message}");
tcs.SetResult(false);
},
() =>
{
_databaseService.CloseConnection(); //Maybe move this to a Finally call?
Console.WriteLine($"Finished");
tcs.SetResult(true);
}
);
return await tcs.Task;
}
公共异步任务MyMethod()
{
var tcs=new TaskCompletionSource();
_databaseService.OpenConnection();
var-dataCount=0;
_dataService.QuerySegmentedObservable(\u sourceTableName)
.SelectMany(异步数据=>
{
wait_databaseService.DoSomething(数据);
返回数据;
})
//.Finally(()=>\u databaseService.CloseConnection())//这将在OnComplete和OnError上调用,就像try Finally一样
.订阅(数据=>
{
dataCount+=data.Count;
WriteLine($“Processing-{dataCount}”);
},
错误=>
{
WriteLine($“Error-{err.Message}”);
tcs.SetResult(假);
},
() =>
{
_databaseService.CloseConnection();//是否可以将此移到Finally调用?
Console.WriteLine($“已完成”);
tcs.SetResult(真);
}
);
返回等待任务;
}
我无法真正测试它,因此我希望这能让您走上正确的道路。如果您需要更多帮助,请发布一个更好的。Rx确实在运营商内部支持async/await。您正在订阅中使用它。因此(希望)您可以将代码更改为以下内容:
public async Task<bool> MyMethod()
{
var tcs = new TaskCompletionSource<bool>();
_databaseService.OpenConnection();
var dataCount = 0;
_dataService.QuerySegmentedObservable<TSource>(_sourceTableName)
.SelectMany(async data =>
{
await _databaseService.DoSomething(data);
return data;
})
//.Finally(() => _databaseService.CloseConnection()) //This would be called on OnComplete and OnError, just like try-finally
.Subscribe(data =>
{
dataCount += data.Count;
Console.WriteLine($"Processing - {dataCount}");
},
err =>
{
Console.WriteLine($"Error - {err.Message}");
tcs.SetResult(false);
},
() =>
{
_databaseService.CloseConnection(); //Maybe move this to a Finally call?
Console.WriteLine($"Finished");
tcs.SetResult(true);
}
);
return await tcs.Task;
}
公共异步任务MyMethod()
{
var tcs=new TaskCompletionSource();
_databaseService.OpenConnection();
var-dataCount=0;
_dataService.QuerySegmentedObservable(\u sourceTableName)
.SelectMany(异步数据=>
{
wait_databaseService.DoSomething(数据);
返回数据;
})
//.Finally(()=>\u databaseService.CloseConnection())//这将在OnComplete和OnError上调用,就像try Finally一样
.订阅(数据=>
{
dataCount+=data.Count;
WriteLine($“Processing-{dataCount}”);
},
错误=>
{
WriteLine($“Error-{err.Message}”);
tcs.SetResult(假);
},
() =>
{
_databaseService.CloseConnection();//是否可以将此移到Finally调用?
Console.WriteLine($“已完成”);
tcs.SetResult(真);
}
);
返回等待任务;
}
我不能真正测试它,所以我希望这能让您走上正确的道路。如果您需要更多帮助,请发布更好的。尝试从
onNext
块中删除异步操作。\u databaseService
的类型是什么?@En它只是一个将数据插入数据库的类,或者做一些可能需要几秒钟的事情OND最多40秒。@redent84我认为rx的新版本支持异步/等待,不是吗?尝试从onNext
块中删除异步操作。\u databaseService
的类型是什么?@En它只是一个将数据插入数据库的类,或者执行一些可能需要几秒钟到40秒的操作。@redent84 I-thought新版本的rx支持异步/等待,否?