【问题标题】:Use the TResult from the Task<TResult> in F#在 F# 中使用来自 Task<TResult> 的 TResult
【发布时间】:2022-10-07 03:39:53
【问题描述】:

我正在使用 F# 脚本将事件发布到 Azure 事件中心。等效的 C# 代码如下:

var connectionString = \"<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>\";
var eventHubName = \"<< NAME OF THE EVENT HUB >>\";

await using (var producer = new EventHubProducerClient(connectionString, eventHubName))
{
    using EventDataBatch eventBatch = await producer.CreateBatchAsync();
    eventBatch.TryAdd(new EventData(new BinaryData(\"First\")));
    eventBatch.TryAdd(new EventData(new BinaryData(\"Second\")));

    await producer.SendAsync(eventBatch);
}

我不认为以下是最好的惯用 F#,尽管它有效:

let producerClient = EventHubProducerClient(connectionString, eventHubName)
let cancellationToken = CancellationToken()
let eventDataBatch = 
  cancellationToken
  |> producerClient.CreateBatchAsync
let edb = eventDataBatch.Result
edb.TryAdd event
producerClient.SendAsync edb

注意:我没有包含创建event 的代码,但它是一个 JSON 字符串。

如何避免拨打Result?这看起来像一个可以更清洁的步骤。

    标签: f# c#-to-f#


    【解决方案1】:

    您可以使用 F# 中的 task { .. } 计算表达式重写使用 C# async/await 的代码。在其中,您可以使用let! 代替await,也可以使用do! 等待不返回结果的任务,使用use! 等待IDisposable 结果。

    我不确定您在这里使用的是什么库,但类似这样的内容说明了语法:

    let connectionString = "<< CONNECTION STRING FOR THE EVENT HUBS NAMESPACE >>";
    let eventHubName = "<< NAME OF THE EVENT HUB >>";
    
    let processEvent() = task {
      use producer = new EventHubProducerClient(connectionString, eventHubName)
      use! eventBatch = producer.CreateBatchAsync()
      eventBatch.TryAdd(EventData(new BinaryData("First")))
      eventBatch.TryAdd(EventData(new BinaryData("Second")))
      do! producer.SendAsync(eventBatch) }
    

    如果您随后调用processEvent(),结果将再次为Task。如果您打算在顶层阻塞,您可以忽略它(并让计算运行),或者等待结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-23
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多