在一个异步函数如何处理没有为ByRef?如何处理、函数、ByRef

2023-09-06 10:51:07 作者:談談訫說說嗳

我正在更换使用线程到.NET 4.5基于任务的系统我的老code。

I'm working on replacing my old code that uses threads to a .NET 4.5 Task based system.

我有,我想转换下面的子;

I have the following sub that I wish to convert;

Public Function Delay(Milliseconds As Integer, ByRef Job As Job) As Boolean
   For i As Integer = 1 To CInt(Milliseconds / 100)
      Thread.Sleep(100)
      If Job.IsCancelled Then Return True
   Next
   Return False
End Function

的Job类是我自己的一个,但重要的是它包含一个整数被设置为1,如果该作业应被取消。因此,延迟功能,可以让我把一个线程睡眠对于x毫秒,但如果作业在这段时间内取消将停止睡眠和返回True。

The Job class is one of my own, but importantly it contains an integer which is set to 1 if the job should be cancelled. So, the Delay function allows me to put a thread to sleep for X milliseconds, but if the job is cancelled during that time it will stop sleeping and return True.

我不知道如何与等待Task.Delay做到这一点,这是我的尝试;

I'm not sure how to do this with Await Task.Delay, here's my attempt;

  Public Async Function Delay(Milliseconds As Integer, Job As Job) As Tasks.Task(Of Boolean)
    For i As Integer = 1 To CInt(Milliseconds / 100)
      Await Tasks.Task.Delay(100)
      If Job.IsCancelled Then Return True
    Next
    Return False
  End Function

我遇到的问题是,异步方法不会允许我使用的ByRef,这意味着它将无法检测时,工作已被取消。另一个问题是,等待不能被里面的try / catch /终于还是的SyncLock使用。我下的是IM pression你可以写异步code,看起来像同步code。我怎样才能解决这些问题得到什么呢?

The problem I'm having is that Async methods don't allow me to use ByRef, which means it won't be able to detect when the Job has been cancelled. Another issue is that await can't be used inside try/catch/finally or a synclock. I was under the impression you can write asynchronous code that looks like synchronous code. How can I get around these issues?

推荐答案

您实际上并不变异在方法的身体工作变量,所以你不应该 T为传递给它引用在所有的,你应该是按值传递给它。

You're not actually mutating the Job variable in the body of your method, so you shouldn't be passing it by reference at all, you should be passing it by value.

也就是说,除非工作实际上是一个可变的值类型,而不是引用类型,在这种情况下的是的是你的问题,你应该不使用一个可变的值类型在这里解决它。

That is, unless Job is actually a mutable value type instead of a reference type, in which case that is your problem and you should fix it by not using a mutable value type here.

另外值得一提的是,如果你想使用一个对象来封装可能取消你应该使用异步操作的的CancellationToken (以及伴随的 CancellationTokenSource )。它将提供所有您需要的功能,并特别注意的,它会处理所有适当的同步,这样你就不会遇到从多个线程访问它的任何问题。这也恰好是引用类型。

It's also worth noting that if you wish to use an object to encapsulate the possible cancellation of an asynchronous operation you should use CancellationToken (and the accompanying CancellationTokenSource). It will provide all of the functionality that you need, and of particular note, it will handle all of the proper synchronization such that you won't run into any problems accessing it from multiple threads. It also happens to be a reference type.

如果你接受的CancellationToken 你也可以将它传递给 Task.Delay ,允许其完成时,令牌将被取消,而不是强迫你的方法要等到延时结束,以返回false

If you accept a CancellationToken you'll also be able to pass it to Task.Delay, allowing it to complete when the token is cancelled, rather than forcing your method to wait until the delay is over to return false.

 
精彩推荐
图片推荐