繁体   English   中英

如何在程序运行时按顺序运行 C# 代码并在视图中显示一些数据

[英]How run C# code in sequence and show some data in view while still program is running

我有一个在 mvc5 中运行的查询。 我需要在屏幕上写开始时间,然后写一些类似加载……然后写下运行完成的时间。 我不知道用什么来按顺序写这个,而不是一次,这是我的代码,它在运行完成后立即编写。

   public IActionResult GetQuery()
    {
        ViewData["Timefrom"] = DateTime.Now;
        
        var Query= _context.Order.FromSqlRaw("EXECUTE [dbo].[GetStatusReport].ToList();
        
        ViewData["Timefrom2"] = DateTime.Now;
        
        return View(Query);
    }

这是我的观点:

 @model IEnumerable<Order>
 @{
   ViewData["Title"] = "Home Page";
 }


<tbody>
Start Time: @ViewData["Timefrom"]   //need this showup 1st before query running 
@foreach (var item in Model)        //show loading when here  
{
    <tr>
        <td width="30%">@item.OrderId</td>
        <td width="30%">@item.Name</td>
        <td width="30%">@item.Location</td>
    </tr>
}  
End Time: @ViewData["Timefrom2"]    //show this at end when done running query

您的案例非常适合称为 WebSocket 的技术。 在 Asp.net MVC 中,您可以使用 SignalR 库以很少的代码行实现 WebSockets。

2021 年 10 月 15 日更新:您可以按照此答案中的示例了解 WebSocket 技术以及如何将其集成到现有的 Asp.net 应用程序中。

例如,您的页面将如何工作:

  • 页面从控制器动作加载。 当页面加载时,您开始繁重的过程
  • 页面加载后,它会连接到服务器上的特定端点(使用 WebSocket)。 使用 WebSocket 连接,服务器和页面将能够根据需要发送/接收数据 - 双向! 在这种情况下,服务器将在需要时向页面发送更新。 页面将接收数据。 并且不必间隔使用 Ajax 拉取数据。
  • 在批量处理中(您在页面加载时已启动)处理数据并向 WebSocket 发送定期更新
  • 任何连接到套接字的客户端都将获取数据(在这种情况下,您的页面是一个客户端)。 您可以使用来自不同页面的相同数据。

这是基于 SignalR 的 WebSocket 的工作原理图(该图像是从此处收集的,您可以在此处获得详细说明):

在此处输入图片说明

这是一个示例集线器:

using AutoMapper;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Hubs
{
    public class ProcessHub : Hub
    {
        private static IHubContext<ProcessHub> _hubContext;
        public static Dictionary<int, List<KeyValuePair<string, string>>> AppClientStorage = new Dictionary<int, List<KeyValuePair<string, string>>>();

        public ProcessHub(IMapper mapper, IHubContext<ProcessHub> hubContext)
        {
            _hubContext = hubContext;
        }

        public async Task<string> RegisterToSocket(int userId)
        {
            KeyValuePair<string, string> keyValuePair = new KeyValuePair<string, string>(subscriptionTypeName, Context.ConnectionId);

            AddToDictionary(userId, keyValuePair);

            return "Successfully Registered.";
        }

        public static async Task NotifyUpdatesRingAsync(int userId)
        {
            if (AppClientStorage.ContainsKey(userId))
            {
                List<KeyValuePair<string, string>> userSubscriptions = AppClientStorage[userId];

                if (userSubscriptions != null)
                {
                    List<KeyValuePair<string, string>> subscribers = userSubscriptions.ToList();

                    foreach (var subsc in subscribers)
                    {
                        string data = "10% Processed. Please wait..."
                        await _hubContext.Clients.Client(subsc.Value).SendAsync("ReceiveProcessData", data);
                    }
                }
            }
        }

        private void AddToDictionary(int userId, KeyValuePair<string, string> keyValuePair)
        {
            if (!AppClientStorage.ContainsKey(userId))
            {
                AppClientStorage.Add(userId, new List<KeyValuePair<string, string>>() { keyValuePair });
            }
            else
            {
                List<KeyValuePair<string, string>> subscriptions = AppClientStorage[userId];
                List<KeyValuePair<string, string>> connectionList = subscriptions.Where(s => s.Key.Equals(keyValuePair.Key)).ToList();

                if (!connectionList.Any(s => s.Value.Equals(keyValuePair.Value)))
                {
                    subscriptions.Add(keyValuePair);
                    AppClientStorage[userId] = subscriptions;
                }
            }
        }
        
        public override Task OnDisconnectedAsync(Exception exception)
        {
            string connectionId = Context.ConnectionId;
            return base.OnDisconnectedAsync(exception);
        }       
    }
}

然后在 CShtml - 页面加载时连接到集线器的代码:

<script type="text/javascript">

    var connection = new signalR.HubConnectionBuilder()
        .withUrl("/processhub")
        .withAutomaticReconnect()
        .build();

    connection.on("ReceiveProcessData", function (data) {
        // Data sent by the server from the NotifyUpdatesProcessAsync function will arrive here
        // Display the 'Data' on the page as needed
    });

    connection.start();

    function subscribe() {
        connection.invoke("RegisterToSocket", 123).then(function (data) {
            // 123 is ur user Id            
            //Display the data as needed
        }).catch(err => console.error(err.toString()));
    }

</script>

在处理数据的 Action/Service 中,只需调用 hub 方法将数据推送到客户端,如下所示:

await ProcessHub.NotifyUpdatesProcessAsync(123);

这里 123 是将获取数据的用户 ID。

如果您不知道如何配置集线器并在启动时将其连接起来,您可以按照网络上的任何教程进行操作。 例如这里是一个.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM