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支持异步/等待,否?