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 に答える