50٪ تخفیف روی تمام دوره‌ها!
پایان تخفیف تا:
مشاهده دوره‌ها
0

توقف AsyncTask و فراخوانی یک متد از Class Library مرجع

سلام

ممنون میشم کمکم کنید. من تازه سی شارپ رو شروع کردم. دارم یک چت بات اینستا مینویسم. یه کوچولو مغزم هنگ کرده سه شبانه روز مقاله و کتاب خوندم به نتیجه نرسیدم.

من یه کلاس توی کلاس لایبری جدا تعریف کردم به اسم فرضی AddressDialog.cs که توی فضای نام TradeBot.BotAssets قرار داره که توسط کنترلی در فضای نام مرجع TradeBot زمانی که کاربر بخواد آدرس بده فراخوانی میشه. اما از اونجایی که واقعی بودن آدرس و کد پستی توسط گوگل مپ چک میشه تا زمانی که Context.Done آدرس خروجی نداشته باشه اجازه ادامه دادن نمیده. این مسئله خوبه اما از اونجایی که ممکنه کاربر منصرف بشه (کد برنامه جوری هستش که History کاربر رو نگه میداره) تا زمانی که با آیدی جدید پیام نده بهش اجازه انجام هیچ کاری نمیده.

میشه شما اساتید گرامی کمک کنید من بتونم یه کلمه کلیدی مثل Cancel تعریف کنم که وقتی کاربر Cancel رو تایپ کرد Task متوقف بشه و یک کلاس Task دیگه از فضای نام مرجع TradeBot به اسم AfterChangeMyMind که توی کلاس لایبری RootDialog قرار داره رو صدا کنم؟

سلام
ممنون میشم کمکم کنید. من تازه سی شارپ رو شروع کردم. دارم یک چت بات اینستا مینویسم. یه کوچولو مغزم هنگ کرده سه شبانه روز مقاله و کتاب خوندم به نتیجه نرسیدم. 
من یه کلاس توی کلاس لایبری جدا تعریف کردم به اسم فرضی AddressDialog.cs که  توی فضای نام TradeBot.BotAssets قرار داره که توسط کنترلی در فضای نام مرجع TradeBot زمانی که کاربر بخواد آدرس بده فراخوانی میشه. اما از اونجایی که واقعی بودن آدرس و کد پستی توسط گوگل مپ چک میشه تا زمانی که Context.Done آدرس خروجی نداشته باشه اجازه ادامه دادن نمیده. این مسئله خوبه اما از اونجایی که ممکنه کاربر منصرف بشه  (کد برنامه جوری هستش که History کاربر رو نگه میداره) تا زمانی که با آیدی جدید پیام نده بهش اجازه انجام هیچ کاری نمیده. 
میشه شما اساتید گرامی کمک کنید من بتونم یه کلمه کلیدی مثل Cancel تعریف کنم که وقتی کاربر Cancel رو تایپ کرد Task متوقف بشه و یک کلاس Task دیگه از فضای نام مرجع TradeBot به اسم AfterChangeMyMind که توی کلاس لایبری RootDialog قرار داره رو صدا کنم؟
||http://tosinso.com/files/get/419bb7fd-7fe9-454a-af3c-cee58a68910e||||http://tosinso.com/files/get/c9fa95d9-5157-4a12-ab67-07208b20ed52||
اینم کدهای کلاس AddressDialog


<c#>
namespace TradeBot.BotAssets.Dialogs
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Extensions;
    using Microsoft.Bot.Builder.Dialogs;
    using Microsoft.Bot.Connector;
    using Properties;
    using TradeBot.Services;

    [Serializable]
    public class AddressDialog : IDialog<string>
    {
        private readonly string prompt;
        private readonly ILocationService locationService;

        private string currentAddress;

        public AddressDialog(string prompt, ILocationService locationService)
        {
            this.prompt = prompt;
            this.locationService = locationService;
        }

        public async Task StartAsync(IDialogContext context)
        {
            await context.PostAsync(this.prompt);
            context.Wait(this.MessageReceivedAsync);
        }

        public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
        {
            var message = await result;

            var addresses = await this.locationService.ParseAddressAsync(message.Text);
            if (addresses.Count() == 0)
            {

                await context.PostAsync(Resources.AddressDialog_EnterAddressAgain);
                context.Wait(this.MessageReceivedAsync);
            }
            else if (addresses.Count() == 1)
            {
                this.currentAddress = addresses.First();
                PromptDialog.Choice(context, this.AfterAddressChoice, new[] { Resources.AddressDialog_Confirm, Resources.AddressDialog_Edit }, this.currentAddress);
            }
            else
            {
                var reply = context.MakeMessage();
                reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;

                foreach (var address in addresses)
                {
                    reply.AddHeroCard(Resources.AddressDialog_DidYouMean, address, new[] { new KeyValuePair<string, string>(Resources.AddressDialog_UseThisAddress, address) });
                }

                await context.PostAsync(reply);
                context.Wait(this.MessageReceivedAsync);
            }
        }

        private async Task AfterAddressChoice(IDialogContext context, IAwaitable<string> result)
        {
            try
            {
                var choice = await result;

                if (choice == Resources.AddressDialog_Edit)
                {
                    await this.StartAsync(context);
                }
                else
                {
                    context.Done(this.currentAddress);
                }
            }
            catch (TooManyAttemptsException)
            {
         <>       throw;
            }
        }
    }
}
<c#>
سلام
ممنون میشم کمکم کنید. من تازه سی شارپ رو شروع کردم. دارم یک چت بات اینستا مینویسم. یه کوچولو مغزم هنگ کرده سه شبانه روز مقاله و کتاب خوندم به نتیجه نرسیدم. 
من یه کلاس توی کلاس لایبری جدا تعریف کردم به اسم فرضی AddressDialog.cs که  توی فضای نام TradeBot.BotAssets قرار داره که توسط کنترلی در فضای نام مرجع TradeBot زمانی که کاربر بخواد آدرس بده فراخوانی میشه. اما از اونجایی که واقعی بودن آدرس و کد پستی توسط گوگل مپ چک میشه تا زمانی که Context.Done آدرس خروجی نداشته باشه اجازه ادامه دادن نمیده. این مسئله خوبه اما از اونجایی که ممکنه کاربر منصرف بشه  (کد برنامه جوری هستش که History کاربر رو نگه میداره) تا زمانی که با آیدی جدید پیام نده بهش اجازه انجام هیچ کاری نمیده. 
میشه شما اساتید گرامی کمک کنید من بتونم یه کلمه کلیدی مثل Cancel تعریف کنم که وقتی کاربر Cancel رو تایپ کرد Task متوقف بشه و یک کلاس Task دیگه از فضای نام مرجع TradeBot به اسم AfterChangeMyMind که توی کلاس لایبری RootDialog قرار داره رو صدا کنم؟
||http://tosinso.com/files/get/419bb7fd-7fe9-454a-af3c-cee58a68910e||||http://tosinso.com/files/get/c9fa95d9-5157-4a12-ab67-07208b20ed52||
اینم کدهای کلاس AddressDialog


<c#>
namespace TradeBot.BotAssets.Dialogs
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Extensions;
    using Microsoft.Bot.Builder.Dialogs;
    using Microsoft.Bot.Connector;
    using Properties;
    using TradeBot.Services;

    [Serializable]
    public class AddressDialog : IDialog<string>
    {
        private readonly string prompt;
        private readonly ILocationService locationService;

        private string currentAddress;

        public AddressDialog(string prompt, ILocationService locationService)
        {
            this.prompt = prompt;
            this.locationService = locationService;
        }

        public async Task StartAsync(IDialogContext context)
        {
            await context.PostAsync(this.prompt);
            context.Wait(this.MessageReceivedAsync);
        }

        public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
        {
            var message = await result;

            var addresses = await this.locationService.ParseAddressAsync(message.Text);
            if (addresses.Count() == 0)
            {

                await context.PostAsync(Resources.AddressDialog_EnterAddressAgain);
                context.Wait(this.MessageReceivedAsync);
            }
            else if (addresses.Count() == 1)
            {
                this.currentAddress = addresses.First();
                PromptDialog.Choice(context, this.AfterAddressChoice, new[] { Resources.AddressDialog_Confirm, Resources.AddressDialog_Edit }, this.currentAddress);
            }
            else
            {
                var reply = context.MakeMessage();
                reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;

                foreach (var address in addresses)
                {
                    reply.AddHeroCard(Resources.AddressDialog_DidYouMean, address, new[] { new KeyValuePair<string, string>(Resources.AddressDialog_UseThisAddress, address) });
                }

                await context.PostAsync(reply);
                context.Wait(this.MessageReceivedAsync);
            }
        }

        private async Task AfterAddressChoice(IDialogContext context, IAwaitable<string> result)
        {
            try
            {
                var choice = await result;

                if (choice == Resources.AddressDialog_Edit)
                {
                    await this.StartAsync(context);
                }
                else
                {
                    context.Done(this.currentAddress);
                }
            }
            catch (TooManyAttemptsException)
            {
         <>       throw;
            }
        }
    }
}
<c#>

اینم کدهای کلاس AddressDialog

namespace TradeBot.BotAssets.Dialogs
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Extensions;
    using Microsoft.Bot.Builder.Dialogs;
    using Microsoft.Bot.Connector;
    using Properties;
    using TradeBot.Services;

    [Serializable]
    public class AddressDialog : IDialog<string>
    {
        private readonly string prompt;
        private readonly ILocationService locationService;

        private string currentAddress;

        public AddressDialog(string prompt, ILocationService locationService)
        {
            this.prompt = prompt;
            this.locationService = locationService;
        }

        public async Task StartAsync(IDialogContext context)
        {
            await context.PostAsync(this.prompt);
            context.Wait(this.MessageReceivedAsync);
        }

        public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
        {
            var message = await result;

            var addresses = await this.locationService.ParseAddressAsync(message.Text);
            if (addresses.Count() == 0)
            {

                await context.PostAsync(Resources.AddressDialog_EnterAddressAgain);
                context.Wait(this.MessageReceivedAsync);
            }
            else if (addresses.Count() == 1)
            {
                this.currentAddress = addresses.First();
                PromptDialog.Choice(context, this.AfterAddressChoice, new[] { Resources.AddressDialog_Confirm, Resources.AddressDialog_Edit }, this.currentAddress);
            }
            else
            {
                var reply = context.MakeMessage();
                reply.AttachmentLayout = AttachmentLayoutTypes.Carousel;

                foreach (var address in addresses)
                {
                    reply.AddHeroCard(Resources.AddressDialog_DidYouMean, address, new[] { new KeyValuePair<string, string>(Resources.AddressDialog_UseThisAddress, address) });
                }

                await context.PostAsync(reply);
                context.Wait(this.MessageReceivedAsync);
            }
        }

        private async Task AfterAddressChoice(IDialogContext context, IAwaitable<string> result)
        {
            try
            {
                var choice = await result;

                if (choice == Resources.AddressDialog_Edit)
                {
                    await this.StartAsync(context);
                }
                else
                {
                    context.Done(this.currentAddress);
                }
            }
            catch (TooManyAttemptsException)
            {
         <>       throw;
            }
        }
    }
}
پرسیده شده در 1395/09/13 توسط

7 پاسخ

0

ممنون.

مقاله رو کلید میکنم تب Blank باز میشه. لینک رو اصلاح میکنید لطفا؟

پاسخ در 1395/09/13 توسط
0

ممنون بابت ویرایش. راهنمایی بهتر از ویرایش کمکم میکنه. متخصصین گرامی کمک

پاسخ در 1395/09/13 توسط
1

سلام و عرض ادب، برای Cancel کردن یک Task شما باید یک Cancellation Token تعریف کنید و از اون برای کنسل کردن Task استفاده کنید. مطلب زیر رو مطالعه کنید در این باره توضیح دادم. شما زمانی که Task ای ایجاد می کنید با مکانیزم ذکر شده می تونید به راحتی Task رو متوقف کنید:

آموزش برنامه نویسی موازی (Parallel Programming) در سی شارپ

پاسخ در 1395/09/13 توسط
0

سلام. با تشکر از پیگیری شما با کمی مطالعه بیشتر در رابطه با نحوه عملکرد Task جواب رو پیدا کردم. اینجا میگم تا شاید سوال مشابه دوستان باشه

باید قبل از اینکه محتوای String به Task AddressDialog ارسال بشه چک بشه و یا در Global.asax.cs خروجی اون Task بصورت عمومی تعریف بشه.

از اونجایی که من قابلیت Cancel شدن رو برای تمام Task ها میخواستم یک کلاس MessageController ساختم و تمام پیام های ارسالی توسط کاربر رو قبل از ارسال به Task کنترل کردم. این هم کلاس کنترل نهایی (کمی ناقص اما جوابگو)<c#>

    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
        try
        {
            if (activity.Type == ActivityTypes.Message)
            {
                string msg = activity.Text.ToLower().Trim();
                if (msg == Resources.CancelCommand)
                {
                      using (var scope =  DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
                           var botData = scope.Resolve<IBotData>();
                           await botData.LoadAsync(default(CancellationToken));
                           var stack = scope.Resolve<IDialogStack>();
                           stack.Reset();
                           await botData.FlushAsync(default(CancellationToken));
                      }
                }

                BotUtils.SendTyping(activity); //send "typing" indicator upon each message received
                await Conversation.SendAsync(activity, () => new RootDialog());
            }
            else
            {
                HandleSystemMessage(activity);
            }
        }

<c#>

پاسخ در 1395/09/15 توسط
0

سلام مجدد، من فردا کد شما رو شبیه سازی میکنم و همین جا در ادامه راهکار رو خدمتتون میفرستم. :)

پاسخ در 1395/09/13 توسط
0

سپاس فراوان استاد بزرگ مهندس احمدی.

من حالا حالا ها باید دست نوشته بخونم تا لایق نام شاگرد بشم مهندس که ....

لینک رو از طریق جستجو پیدا کردم با توجه به اینکه نتونستم استفاده کنم گفتم لینک صحیح باشه برای دیگر دوستانی که ممکنه سوال مشابه داشته باشن.

همچنان نیازمند یک راهنمایی برای سوالم با توجه به کد ارسالی هستم. نمیخوام دوباره کاری کنم و همه کد ها رو توی یک کلاس لایبری ببرم. مثلا سعی کردم تمیز کار کنم.

دومین پروژه ای هست که دارم کار میکنم. کم تجربگی آزار و اذیتاش رو شروع کرده

پاسخ در 1395/09/13 توسط

پاسخ شما