1

私はこの非非同期の Task> を持っていますが、これは単に要求するだけです:

TaskCompletionSource<ObservableCollection<ItemDto>> tcs = new TaskCompletionSource<ObservableCollection<ItemDto>>();

        ObservableCollection<ItemDto> results = new ObservableCollection<ItemDto>();

        try
        {
            BasicHttpBinding binding = new BasicHttpBinding();
            binding.OpenTimeout = new TimeSpan(0, 0, 30);
            binding.CloseTimeout = new TimeSpan(0, 0, 30);
            binding.SendTimeout = new TimeSpan(0, 0, 30);
            binding.ReceiveTimeout = new TimeSpan(0, 0, 30);

            MobileClient clientMobile = new MobileClient(binding, new EndpointAddress(_endpointUrl));

            clientMobile.FindItemsCompleted += (object sender, FindItemsCompletedEventArgs e) =>
            {
                if (e.Error != null)
                {
                    _error = e.Error.Message;
                    tcs.TrySetException(e.Error);
                }
                else if (e.Cancelled)
                {
                    _error = "Cancelled";
                    tcs.TrySetCanceled();
                }

                if (string.IsNullOrWhiteSpace(_error) && e.Result.Count() > 0)
                {
                    results = SetItemList(e.Result);

                    tcs.TrySetResult(results);
                }
                clientMobile.CloseAsync();
            };
            clientMobile.FindItemsAsync(SetSearchParam(searchString, 100));
        }
        catch (Exception)
        {
            results = new ObservableCollection<ItemDto>();
            tcs.TrySetResult(results);
        }
        return tcs.Task;

はい、わかっています、特別なことは何もありません。

clientMobile.FindItemsAsync(SetSearchParam(searchString, 100))

void メソッドの呼び出しです。このメソッドは、いくつかのパラメータを設定する別の void メソッドを呼び出してから、非同期操作を実行してアイテムのリストを返す非同期メソッドを呼び出す非同期メソッドを呼び出します。

問題は、上記のこのタスクの範囲を超えて何も制御できないことです.私の仕事をそれに適応させるのが私のポリシーなので... -_-

そのためには、FindItemsAsync へのこの呼び出しを強制終了する必要があります。合計 1 分が経過するとすぐに...上記のタイムスパンをそれぞれ 1 分に設定してみました (最初は機能しましたが、いくつかの変更が加えられました)。だめ)、半分の時間に減らしてみましたが、だめでした...

このタスクを呼び出すコードは次のとおりです。

public void LoadItemList(string searchString)
    {
        _itemList = new ObservableCollection<ItemDto>();

        // Calls the Task LoadList.
        var result = LoadList(searchString).Result;

        if (result != null && result != new ObservableCollection<ItemDto>())
        {
            _itemList = result;
        }
        else
        {
            _isTaskCompleted = false;
        }

        _isListEmpty = (_itemList != new ObservableCollection<ItemDto>()) ? false : true;
    }

以下は、このタスクの呼び出し元を呼び出すコードです...(なんて混乱-_-):

void Init(string searchString = "")
    {
        Device.BeginInvokeOnMainThread(async () =>
        {
            if (!LoadingStackLayout.IsVisible && !LoadingActivityIndicator.IsRunning)
            {
                ToggleDisplayLoadingListView(true);
            }

            await Task.Run(() => _listVM.LoadItemList(searchString));

            ToggleDisplayLoadingListView();

            if (!string.IsNullOrWhiteSpace(_listVM.Error))
            {
                await DisplayAlert("Error", _listVM.Error, "OK");
            }
            else if (_listVM.AdList != null && !_listVM.IsListEmpty)
            {
                ItemListView.IsVisible = true;

                ItemListView.ItemsSource = _listVM.ItemList;
            }
            else if (!_listVM.IsTaskCompleted || _listVM.IsListEmpty)
            {
                await DisplayAlert("", "At the moment it is not possible to show results for your search.", "OK");
            }
            else if (_listVM.ItemList.Count == 0)
            {
                await DisplayAlert("", "At the moment there are no results for your search.", "OK");
            }
        });
    }

現時点では、MVVM アーキテクチャを実装しようとしています...

本当に、この件に関してご協力いただきありがとうございます。大変お世話になりました。ご迷惑をおかけして本当に申し訳ありません...

編集

私の目的を明確に説明していなかったため、申し訳ありません。つまり、void メソッド FindItemsAsync を介して通信するだけの API にアクセスするアイテムのリストを取得する必要があります。これらすべてのアイテムを取得するのに 60 秒かかります。何か問題が発生した場合、またはタイムアウトした場合は、プロセスをキャンセルして、問題が発生したことをユーザーに通知する必要があります。

そんなことはありません。キャンセルすることはありません。アイテムを取得するか、永遠にロードし続けるかのどちらかです...私はタスクとこのようなもののほとんどに慣れていないため、常に問題が発生します...

4

1 に答える 1

2

キャンセル トークンの有効期限が切れたら、CloseAsync を呼び出すことができます。

//Creates an object which cancels itself after 5000 ms
var cancel = new CancellationTokenSource(5000);

//Give "cancel.Token" as a submethod parameter
public void SomeMethod(CancellationToken cancelToken)
{
    ...

    //Then use the CancellationToken to force close the connection once you created it
    cancelToken.Register(()=> clientMobile.CloseAsync());
}

接続を切断します。

于 2016-04-29T11:42:14.027 に答える