实现C#方法返回F#中的Task <t>

时间:2015-06-12 00:05:40

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

我在F#中创建了一个继承自C#类的类型,该类公开了一个在C#中返回Task<T>的方法。我试图找出在F#中做到这一点的最佳方式

说我的C#看起来像这样:

public class Foo {
    public TextWriter Out { get { return Console.Out; } }

    public virtual Task<SomeEnum> DoStuff() {
        return Task.FromResult(SomeEnum.Foo);
    } 
}

public enum SomeEnum {
    Foo,
    Bar
}

我在F#中继承该类型的第一步看起来是这样的:

type Bar() =
    inherits Foo()

    override this.DoStuff() =
        this.Out.WriteLineAsync("hey from F#") |> ignore

        System.Threading.Task.FromResult(SomeEnum.Bar)

但是a)它并不觉得它实际上是异步的,而b)它只是感觉不是-F#。

那么我将如何继承Foo类并实现期望返回DoStuff的{​​{1}}方法?

3 个答案:

答案 0 :(得分:11)

您可以使用Async.StartAsTask

ReentrantReadWriteLock

type Bar() = inherit Foo() override this.DoStuff() = async { return SomeEnum.Bar } |> Async.StartAsTask Async.StartAsTask作为输入,并返回Async<T>

答案 1 :(得分:1)

执行异步的F#方法是使用asynchronous workflows。不幸的是,they don't support awaiting non-generic Tasks。但是使用上述问题中的一个解决方法,您的代码可能如下所示:

public void setChartData(BarChartData data) {
    this.chartData = data;
    addBarDataToUi();
}


void addBarDataToUi() {
    Log.d(TAG, "Add bar data to UI called");
    if (chartData != null) {
        //this.removeAllViews(); -> first one I tried, no luck, not displaying views after `addView`
        //this.removeAllViewsInLayout(); -> tried this too but no luck
        this.removeViewsInLayout(0, this.getChildCount()); // again, to no avail :(
        for (int i = 0, count = chartData.getItemCount(); i < count; i++) {
            addBarItemDataUi(chartData.getItemByPos(i));
        }
        Log.d(TAG, "Child count: " + this.getChildCount());
    }
}

void addBarItemDataUi(BarItemData data) {
    LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.bar_chart_item, this, false);
    FrameLayout mainLayout = (FrameLayout) layout.findViewById(R.id.bar_chart_item_main_layout);
    //TextView topText = new TextView(getContext());
    TextView topText = (TextView) layout.findViewById(R.id.bar_chart_item_top_text);
    TextView bottomText = (TextView) layout.findViewById(R.id.bar_chart_item_bottom_text);

    topText.setText(String.valueOf(data.percentage));
    bottomText.setText(data.title);
    mainLayout.setBackgroundColor(data.backgroundColor);
    Log.d(TAG, "Height: " + this.getMeasuredHeight() + ", Top text height: " + topText.getMeasuredHeight());
    int heightRel = (int) (data.getPercentageFractal() * (double) this.getMeasuredHeight());

    mainLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, heightRel));

    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f);
    params.gravity = Gravity.BOTTOM;

    layout.setLayoutParams(params);

    this.addView(layout);

}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
    Log.d(TAG, "On layout..");
    if (chartData != null) {
        addBarDataToUi();
    }
}

答案 2 :(得分:-1)

我相信FSharp包装任务的方法是使用

var a = Async.AwaitIAsyncResult(somecsharpreturningtask) |> ignore