使用ShutdownAsync

时间:2018-01-03 17:03:32

标签: c# grpc

我希望干净地关闭我的表单应用程序,同时正在进行grpc通话。我认为ShutdownAsync会关闭所有正在进行的通话,但似乎我没有把它放在正确的地方,或者它不负责关闭频道。什么是实现全能的最简单方法,在应用程序关闭时以CompleteAsync()结束所有流?

我使用另一个类来保存所有grpc的东西还有一个额外的困难,我不知道什么时候收集垃圾。当然,我可以做一个取消令牌并在我关闭时取消所有正在进行的通话,但同样,我应该在哪里取消?在Model的析构函数或View的析构函数中?

示例代码:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

using Grpc.Core;
using OdinIntegrationSyncRPC;

namespace MinViaExample
{
    public partial class Form1 : Form
    {
        ExampleModel ex;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ex = new ExampleModel();
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            ex.Sync();
        }

        private async void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            await ex.ShutdownChannelAsync();
        }
    }

    public class ExampleModel
    {
        Channel channel;
        OdinIntegrationSync.OdinIntegrationSyncClient client;

        private AsyncDuplexStreamingCall<LSHeartbeat, LastStudentsPacket> CurrentCall;

        public ExampleModel()
        {
            channel = new Channel("127.0.0.1:50052", ChannelCredentials.Insecure);
            client = new OdinIntegrationSync.OdinIntegrationSyncClient(channel);
        }

        public async void Sync()
        {
            var CTokenSource = new CancellationTokenSource();
            CancellationToken CToken = CTokenSource.Token;

            using (CurrentCall = client.GetLastStudentSync())
            {
                await CurrentCall.RequestStream.WriteAsync(new LSHeartbeat() { ContinueRequest = true });

                while (await CurrentCall.ResponseStream.MoveNext(CancellationToken.None) && !CToken.IsCancellationRequested)
                {
                    LastStudentsPacket lsp = CurrentCall.ResponseStream.Current;
                    foreach (OStudent o in lsp.Students)
                    {
                        // blahblah
                    }
                    await CurrentCall.RequestStream.WriteAsync(new LSHeartbeat() { ContinueRequest = true });
                }
            }
            await CurrentCall.RequestStream.CompleteAsync();
        }

        public async Task ShutdownChannelAsync()
        {
            await channel.ShutdownAsync();
        }
    }
}

编辑:上面的代码已从最初的问题(添加ShutdownChannel调用添加到FormClosing)更改。现在只有服务器崩溃System.InvalidOperationException: 'Already finished.'。客户似乎干净利落地退出。

如果我错过了一些基本的东西,请道歉。

0 个答案:

没有答案