【问题标题】:How to determine whether Task.Run is completed within a loop如何判断Task.Run是否在循环内完成
【发布时间】:2015-01-04 10:17:46
【问题描述】:

这可能是一个奇怪的问题,它确实是为了我的教育目的,所以我可以将它应用到未来可能出现的场景中。

我正在使用 C#。

我正在进行压力测试,所以这不是完全生产代码。

我通过网络服务将数据上传到我的服务器。

我使用 Run.Task 启动服务。

在允许下一个 Run.Task 开始之前,我会检查任务是否已完成。

这是在一个循环中完成的。

但是,因为我使用的是模块化声明的Task,结果会不会受到影响? 我可以声明一个本地 Task.Run 变量,但我想看看我在第一个问题上能走多远。

如果 Task.Run 可以引发事件表明它已完成,那么这可能不是问题吗?

这是我的代码:

//模块声明:

private static Task webTask = Task.Run(() => { System.Windows.Forms.Application.DoEvents(); });

//在通过定时器调用的函数中

if (webTask.IsCompleted)
{
   //keep count of competed tasks
}


webTask = Task.Run(() =>
{
    try 
    { 
         wcf.UploadMotionDynamicRaw(bytes);  //my web service
    }
    catch (Exception ex)
    {
        //deal with error
    }
);

【问题讨论】:

  • 使用Task Continuation。有不同的莫迪。其中之一是在任务完成后做某事。 IMO 您不需要计时器 - 将您的代码更改为 webTask.ContinueWith...
  • @pasty 嗨,感谢您的快速回复。我现在会看看这个并报告 - 谢谢:)
  • @pasty 所以当我修改我的代码时:
  • webTask = new Task(wcf.UploadMotionDynamicRaw(bytes));
  • 它给了我一个错误'无法从'void'转换为'Action'?

标签: c# task


【解决方案1】:

IMO 你不需要计时器。使用 Task Continuation订阅done 事件:

System.Threading.Tasks.Task
.Run(() => 
{
    // simulate processing
    for (var i = 0; i < 10; i++)
    {
        Console.WriteLine("do something {0}", i + 1);
    }
})
.ContinueWith(t => Console.WriteLine("done."));

输出是:

do something 1
do something 2
.
.
do something 9
do something 10
done

您的代码可能如下所示:

var webTask = Task.Run(() =>
{
    try 
    { 
        wcf.UploadMotionDynamicRaw(bytes);  //my web service
    }
    catch (Exception ex)
    {
        //deal with error
    }
}).ContinueWith(t => taskCounter++);

如果您只想计算成功的任务 - 使用TaskContinuationOptrions,您甚至可以区分失败成功 进程结果。

【讨论】:

  • 您好,我使用计时器只是为了进行压力测试,完全同意您的看法。 MSDN 上的示例与您的不同,我更喜欢您的示例。清晰得多。谢谢
【解决方案2】:

您可以通过像这样等待您的任务来等待您的任务完成

await webTask;

这将异步等待“webTask”完成。您可以使用await Task.Delay 而不是计时器,它将异步等待延迟到期。我还会考虑使 wcf 调用异步,这样您就不必在 Task.Run 内部调用。请参阅this question 了解一些提示。

我将代码重写如下:

public async Task UploadAsync()
{
    while(true)
    {
        await Task.Delay(1000); // this is essentially your timer

        // wait for the webTask to complete asynchrnously
        await webTask;

        //keep count of competed tasks

        webTask = Task.Run(() =>
                        {
                            try 
                            { 
                                // consider generating an asynchronous method for this if possible.
                                wcf.UploadMotionDynamicRaw(bytes);  //my web service
                            }
                            catch (Exception ex)
                            {
                                //deal with error
                            }
                        });     
    }
}

【讨论】:

  • 您好,感谢您提供不同的答案。非常感激。我知道等待,但我想要异步。这一切的原因是为了监控 Web 服务器是否跟上我的重复调用。通过监控队列,我可以(希望)检测到这一点。
猜你喜欢
  • 2014-06-08
  • 1970-01-01
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 2017-12-12
  • 2011-11-19
  • 1970-01-01
  • 2020-01-06
相关资源
最近更新 更多