从void类型的方法中返回一个Task

6
我想创建一个运行串行命令的任务。目前,我不需要从执行工作的方法中返回任何内容。这可能会在以后改变,但现在我很好奇如何实现这一点。
这是我的代码。我想使用一个单独的方法来处理任务,而不是创建一个匿名操作。我尝试了返回void,结果是“void不能明确转换为Task”。我还尝试了Task<void>。最后我尝试了返回一个Task,但我收到了错误消息“Not all Code paths return a value”和“Can not implicily convert void to type task”。

enter image description here

过去我用线程来实现,但这次我想使用任务。

internal class Hardware
{
    private EventHandler<SequenceDoneEventArgs> SequenceDone;

    private List<Step> Steps;
    private System.IO.Ports.SerialPort comport = null;

    private Task SequenceTask;
    private CancellationTokenSource RequestStopSource;
    private CancellationToken RequestStopToken;


    private void Initialize()
    {
        comport = new System.IO.Ports.SerialPort("COM2", 115200, System.IO.Ports.Parity.None,8);
        comport.DataReceived += Comport_DataReceived;
    }

    public async void RunSequence()
    {
        if (comport == null)
        {
            Initialize();
        }
        if (!comport.IsOpen)
        {
            comport.Open();
        }

        RequestStopSource = new CancellationTokenSource();
        RequestStopToken = RequestStopSource.Token;

        SequenceTask = await Task.Run(() => { doSequence(); });

    }

    private Task doSequence()
    {
        //** Run Sequence stuff here

    }
}

预计时间:

最终这是我的完整解决方案

internal class Hardware
{
    private EventHandler<SequenceDoneEventArgs> SequenceDone;

    private List<Step> Steps;
    private System.IO.Ports.SerialPort comport = null;

    private Task SequenceTask;
    private CancellationTokenSource RequestStopSource;
    private CancellationToken RequestStopToken;


    private void Initialize()
    {
        comport = new System.IO.Ports.SerialPort("COM2", 115200, System.IO.Ports.Parity.None,8);
        comport.DataReceived += Comport_DataReceived;
    }

    public async void RunSequence()
    {
        if (comport == null)
        {
            Initialize();
        }
        if (!comport.IsOpen)
        {
            comport.Open();
        }

        RequestStopSource = new CancellationTokenSource();
        RequestStopToken = RequestStopSource.Token;

        SequenceTask = await Task.Factory.StartNew(async () => { await doSequence(); });

    }

    private Task doSequence()
    {
        //** Run Sequence stuff here

        //return null;
        return Task.CompletedTask;
    }
}

3
只需返回Task - default
1
什么是构造函数?什么是操作?什么是“简单的新任务”?如果一个任务没有“返回值”,那它就只是一个任务。如果你想要返回一些东西,你可以使用泛型,即Task<T>。但你不一定需要这样做。你能解释一下为什么使用Task是不正确的吗? - default
1
你正在寻找Task.FromResult()吗? - default
问题已更新,附有屏幕截图。 - TheColonel26
Task.FromResult() 不适用于返回 void 的操作。 - Cata Hotea
显示剩余2条评论
2个回答

6

只需将doSequence标记为async(假设它使用await):

private async Task doSequence()

此外,在您传递给Task.Run的委托中返回此Task是一个好主意:
SequenceTask = await Task.Run(() => doSequence());

我希望创建一个任务来运行串行命令。
这让我认为,在您的情况下使用asyncTask可能不是最好的解决方案。我建议您研究TPL Dataflow。

2
SequenceTask = await Task.Factory.StartNew(async() => { await doSequence(); });

同时,您的RunSequence()应该返回Task而不是void

实际上,如果您等待Task,这应该会产生相同的结果:

SequenceTask = await doSequence();

1
这可能是最接近的了。最终我需要执行 SequenceTask = await Task.Factory.StartNew(async () => { await doSequence(); }); - TheColonel26
Task.Run() 对小猫更友好。 - user585968

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接