因为结果的任务死锁(Task deadlocks because of Result)

2019-10-20 00:53发布

我有以下结构:一个基类,它确实异步一些加载任务和继承类只有基类的结果转换成一个特殊的数据类型(它只是一个通用版本的一些扩展,但这些都不是重要的)。

我最初调用继承类的进程与方法:

    public TOut Process(object parameters)
    {
        return (TOut) StartProcessor(parameters).Result;
    }

此方法调用基础的方法如下:

    protected async Task<object> StartProcessor(object parameters)
    {
        if (State == PipelineState.Running) return null;
        if (!ValidatePipeline())
        {
            Logging.Error(
                "Pipeline can't start processor: There are some broken segment chain-links. Check your segment settings.");
            return null;
        }

        State = PipelineState.Running;
        _stopwatch.Start();

        object result = await Task.Run(() => RunPipeline(parameters));

        _stopwatch.Stop();

        if (result is PipelineState)
            State = (PipelineState) result;
        State = result != null ? PipelineState.Finished : PipelineState.Failed;

        RecentProcessTime = _stopwatch.Elapsed;
        _stopwatch.Reset();
        Logging.Debug("Finished process for pipeline {0} in: {1} ms.", Identifier,
            RecentProcessTime.TotalMilliseconds);

        return result;
    }

    private object RunPipeline(object parameter)
    {
        object recentResult = null;
        for (int i = 0; i < SegmentCount; i++)
        {
            if (_cancelProcess) // Cancel process
                return PipelineState.Cancelled;

            PipelineSegmentBase seg = Segments[i];
            if (i == 0) // If first, do initial process
            {
                recentResult = seg.Process(parameter, ProcessingDirection);
                continue;
            }
            if (i > 0 && recentResult == null) // If not first and recent result was null, process failed
                return PipelineState.Failed;

            seg.Process(recentResult, ProcessingDirection); // Process
        }

        return recentResult ?? PipelineState.Failed;
    }

现在,当然,这是因为结果属性的继承的类处理法死锁。 但我如何赫克能避免这种情况? 我看到了很多的文章,其是伟大的空隙的方法。 但我得到的东西我一定要返回到调用类。 我必须在工艺方法返回一个任务? 我能做些什么使这个异步运行,而它仍然在最后返回的对象?

我真的不明白......随着空洞的方法很简单,但我需要得到这个任务的结果,它死锁。 我不明白这个应该怎么过工作: - /

编辑:这显然会发生...

    public override object Process(object input, PipelineDirection direction)
    {
        if (!IsValidInput(input)) return null;
        Stream str = (Stream) input;
        // DEADLOCK
        return Core.IDE.GetGUICore().GetUIDispatcher().Invoke(() =>
        {
            Image i = new Image();
            i.BeginInit();
            i.Source = BitmapFrame.Create(str);
            i.EndInit();
            return i;
        });
    }

谢谢

Answer 1:

我必须在工艺方法返回一个任务?

这是最好的解决办法,是:

public Task<TOut> ProcessAsync(object parameters)
{
    return StartProcessorAsync(parameters);
}

我能做些什么使这个异步运行,而它仍然在最后返回的对象?

这两个报表没有意义在一起。 想想吧。 你希望它异步运行,但同步返回结果。

最好的解决办法是允许的代码是异步的。 如果StartProcessorAsync是异步的,则调用应该是异步的,做的一切。 这是编写异步代码的自然方式。

有各种各样的黑客,试图获得在异步同步工作,但没有一个在所有情况下工作-因为,在某些方面,这些黑客的人都必须设法迫使异步工作同步完成。 这只是不干净的工作; 最好的解决办法是允许异步工作是异步的。



文章来源: Task deadlocks because of Result