从类型为void的方法返回任务

The*_*l26 2 c# task

我想创建一个运行串行命令的任务.这时我不需要从正在进行工作的方法中返回任何内容.这可能会在以后改变,但我现在很好奇这是怎么回事.

这就是我所拥有的.我想为该任务使用单独的方法,而不是创建匿名操作.我试过返回void,结果是"void无法显式转换为Task".我也试过了.Task<void>.我尝试过的最后一件事是返回一个任务,但我收到了,错误"并非所有代码路径都返回一个值"和"不能暗示将void转换为类型任务"

在此输入图像描述

在传递中我使用了一个Thread来完成这个,但是这次我想使用Tasks.

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

    }
}
Run Code Online (Sandbox Code Playgroud)

ETA:

最后,这是我的完整解决方案

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*ary 5

只需标记doSequenceasync(假设使用await):

private async Task doSequence()
Run Code Online (Sandbox Code Playgroud)

此外,最好Task在您传递给的委托中返回此内容Task.Run:

SequenceTask = await Task.Run(() => doSequence());
Run Code Online (Sandbox Code Playgroud)

我想创建一个运行串行命令的任务.

这让我相信使用asyncTask可能不是您的方案的最佳解决方案.我建议你研究一下TPL Dataflow.


Dom*_*nik 2

SequenceTask = await Task.Factory.StartNew(async() => { await doSequence(); });
Run Code Online (Sandbox Code Playgroud)

另外你RunSequence()应该返回Task而不是void.

实际上,如果你等待Task这应该会导致相同的结果:

SequenceTask = await doSequence();
Run Code Online (Sandbox Code Playgroud)