Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#同步方法调用终止当前处理_C#_Wpf_Multithreading - Fatal编程技术网

C#同步方法调用终止当前处理

C#同步方法调用终止当前处理,c#,wpf,multithreading,C#,Wpf,Multithreading,我有一个绑定到WPF视图的ObservableCollection。有一种方法可以刷新集合的内容。此方法正在后台线程中处理,需要几秒钟的时间。为了避免错误,调用的方法是同步的 即使之前的处理尚未完成,也可能会调用该方法。在这种情况下,我希望停止当前处理并启动新的处理 private ObservableCollection<string> col = new ObservableCollection<string>(); private async void Refre

我有一个绑定到WPF视图的
ObservableCollection
。有一种方法可以刷新集合的内容。此方法正在后台线程中处理,需要几秒钟的时间。为了避免错误,调用的方法是同步的

即使之前的处理尚未完成,也可能会调用该方法。在这种情况下,我希望停止当前处理并启动新的处理

private ObservableCollection<string> col = new ObservableCollection<string>();

private async void Refresh()
{
    var ui = TaskScheduler.FromCurrentSynchronizationContext();
    await Task.Factory.StartNew(() =>
        {
            return GetNewObjects();
        }).ContinueWith(t =>
        {
            col = t.Result;
        }, ui); 
}

[MethodImpl(MethodImplOptions.Synchronized)]
private ObservableCollection<string> GetNewObjects() 
{
    // processing
}
private observetecollection col=new observetecollection();
私有异步无效刷新()
{
var ui=TaskScheduler.FromCurrentSynchronizationContext();
等待任务。工厂。开始新建(()=>
{
返回GetNewObjects();
}).ContinueWith(t=>
{
col=t.结果;
},用户界面);
}
[MethodImpl(MethodImplOptions.Synchronized)]
私有ObservableCollection GetNewObjects()
{
//加工
}

我的想法是在Refresh()中保存相应的
任务的引用
,如果已经有正在运行的任务,则签入每个调用。这是停止任务的正确(安全)方法吗?

您应该始终遵循
async
/
wait
路径

要取消任务,请使用
CancellationTokenSource
及其
CancellationToken

private ObservableCollection<string> col = new ObservableCollection<string>();

private CancellationTokenSource _refreshCancellation;

private async void Refresh()
{
    // cancel the last Refresh action
    if ( _refreshCancellation != null )
    {
        _refreshCancellation.Cancel();
    }

    _refreshCancellation = new CancellationTokenSource();
    var token = _refreshCancellation.Token;

    try
    {
        var newObjects = await GetNewObjectsAsync( token );
        col = new ObservableCollection<string>( newObjects );
    }
    catch ( OperationCanceledException )
    {
    }

}

private async Task<ICollection<string>> GetNewObjectsAsync( CancellationToken cancellationToken )
{
    for ( int i = 0; i < 5; i++ )
    {
        await Task.Delay( 100 ).ConfigureAwait( false );
        // check if we had to cancel, but only where it is safe to cancel
        cancellationToken.ThrowIfCancellationRequested();
    }
    return new List<string> { "a", "b", "c", };
}
private observetecollection col=new observetecollection();
私有取消令牌源\u刷新取消;
私有异步无效刷新()
{
//取消上次刷新操作
如果(_refreshCancellation!=null)
{
_refreshCancellation.Cancel();
}
_refreshCancellation=新的CancellationTokenSource();
var token=\u refreshCancellation.token;
尝试
{
var newObjects=await GetNewObjectsAsync(令牌);
col=新的可观测集合(新对象);
}
捕获(操作取消异常)
{
}
}
专用异步任务GetNewObjectsAsync(CancellationToken CancellationToken)
{
对于(int i=0;i<5;i++)
{
等待任务。延迟(100)。配置等待(false);
//检查我们是否必须取消,但只在安全的情况下取消
cancellationToken.ThrowIfCancellationRequested();
}
返回新列表{“a”、“b”、“c”、};
}

您可能会尝试使用
取消令牌。顺便问一下,为什么不
Task.Run()
?您是否坚持使用.NET 4.0?老实说,没有。。我对.net一无所知。我正在寻找一种很好的方法来刷新视图,而不冻结ui线程。这是我的第一个工作方式。为什么要使用Task.Run()?有什么好处?我认为这是不可能的。UI线程上的延续是一个致命的细节,并且总是会导致死锁。并非唯一的问题,GetNewObjects()必须使用UI中的某种数据来生成不同的结果。我们看不到,但唯一有意义的是。您不能允许该数据在执行时更改。每次单击另一个ObservableCollection中的复选框时,都将调用GetNewObjects()。每个选中的复选框都将是GetNewObjects()方法的输入。实际上,“[MethodImpl(MethodImplOptions.Synchronized)]会导致顺序处理。但这就是问题所在。当方法被调用2次时,有趣的结果是最后一次调用。每次调用后,前面的结果不再相关。
Task.Run()
是在.NET 4.5+中启动任务的首选方法,请阅读以了解详细信息。感谢您的建议。我的后台任务是SQL查询,而不是循环。所以我需要终止这个SQL操作。是否可以通过CancellationToken实现这一点?在阅读了这里的帖子和这些令牌的功能之后,我发现了这个新问题。如果你有新问题,那么如果你找不到任何解决方案,你应该问一个新问题。这就是SO的工作原理这里有一个关于如何处理取消SQL查询的问题,谢谢你的帮助。。你说得对。我遇到了一个新问题。我会尽力解决这个问题。否则我会问一个新问题。然而,你的回答解决了这个问题。