3

当页面加载时,我会在我的中心开始一项新任务。此任务将数据发送到浏览器以更新某些 html 元素。当我浏览离开页面时,我想停止任务。

问题是在任务停止之前(由于它的 sleep 参数),tokenSource = new CancellationTokenSource(); 在该任务的前一个实例有机会停止之前设置了一个新的。

我要做的是在从页面浏览到不需要signalR的不同页面时停止任务。但也许,如果它只是对同一页面的刷新,就不要停止它。不知道该怎么做。总而言之,我想保证只有这个任务的 1 个实例正在运行(并且只在需要它/或有监听器的页面上)任何信息都非常感谢。谢谢

代码:

public class TaskActionStatus : Hub
{
    #region Static Fields

    /// <summary>
    /// The token source.
    /// </summary>
    private static CancellationTokenSource tokenSource;

    /// <summary>
    /// The url string.
    /// </summary>
    private static string url = string.Empty;

    #endregion

    #region Public Methods and Operators

    /// <summary>
    /// The get tasks status.
    /// </summary>
    /// <param name="siteId">
    /// The site id.
    /// </param>
    /// <param name="location"></param>
    public void GetTasksStatus(int? siteId)
    {
        var taskRepository = UnityContainerSetup.Container.Resolve<ITaskRepository>();

        tokenSource = new CancellationTokenSource();
        CancellationToken ct = tokenSource.Token;

        // init task for checking task statuses
        var tasksItem = new DownloadTaskItem();

        // start task only if at least one listener
        if (UserHandler.ConnectedIds.Count < 2 && !taskRepository.IsTasksStatusAsyncRunning())
        {
            taskRepository.GetTasksStatusAsync(siteId, tasksItem, ct);

            // subscribe to event [ listener ]
            tasksItem.Changed += this.UpdateTasksStatus;
        }
        else tokenSource.Cancel();
    }

    /// <summary>
    /// The on connected.
    /// </summary>
    /// <returns>
    /// The <see cref="Task"/>.
    /// </returns>
    public override Task OnConnected()
    {
        UserHandler.ConnectedIds.Add(this.Context.ConnectionId);
        return base.OnConnected();
    }

    /// <summary>
    /// The on disconnected.
    /// </summary>
    /// <returns>
    /// The <see cref="Task"/>.
    /// </returns>
    public override Task OnDisconnected()
    {
        UserHandler.ConnectedIds.Remove(this.Context.ConnectionId);
        if (UserHandler.ConnectedIds.Count == 0)
        {
            try
            {
                    tokenSource.Cancel();
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }

        return base.OnDisconnected();
    }

    /// <summary>
    /// The update tasks status.
    /// </summary>
    /// <param name="sender">
    /// The sender.
    /// </param>
    /// <param name="e">
    /// The e.
    /// </param>
    public void UpdateTasksStatus(object sender, TaskEventArgs e)
    {
        this.Clients.All.updateMessages(e.Tasks);
    }

    #endregion
}

/// <summary>
/// The user handler.
/// </summary>
public static class UserHandler
{
    #region Static Fields

    /// <summary>
    /// The connected ids.
    /// </summary>
    public static HashSet<string> ConnectedIds = new HashSet<string>();

    #endregion
}


    public bool IsTasksStatusAsyncRunning()
    {
        if (tasksStatusAsync != null && tasksStatusAsync.Status.Equals(TaskStatus.Running))
        {
            return true;
        }

        return false;
    }
4

1 回答 1

2

移动这条线:

            tokenSource = new CancellationTokenSource();
            CancellationToken ct = tokenSource.Token;

...使它成为:

       if (UserHandler.ConnectedIds.Count < 2)
        {
            Trace.WriteLine("GetTasksStatus: Starting new task");

            tokenSource = new CancellationTokenSource();
            CancellationToken ct = tokenSource.Token;

            taskRepository.GetTasksStatusAsync(siteId, tasksItem, ct);

            // subscribe to event [ listener ]
            tasksItem.Changed += this.UpdateTasksStatus;
        }

为我做的。谢谢

于 2012-12-10T06:32:05.257 回答