?
Solved

Delphi Thread Stop

Posted on 2007-08-06
5
Medium Priority
?
5,360 Views
Last Modified: 2013-11-23
Can some one make me stop button that will stop all threads that runs in background. Thank you.

Here is the code:


Unit1.dfm
=======

object Form1: TForm1
  Left = 51
  Top = 154
  Width = 674
  Height = 418
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnClose = FormClose
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object ListBox1: TListBox
    Left = 8
    Top = 8
    Width = 225
    Height = 137
    ItemHeight = 13
    Items.Strings = (
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.yahoo.co.in/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.yahoo.co.in/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.yahoo.co.in/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.yahoo.co.in/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.yahoo.co.in/')
    TabOrder = 0
  end
  object ListView1: TListView
    Left = 8
    Top = 152
    Width = 649
    Height = 201
    Columns = <
      item
        Caption = 'Path'
        Width = 200
      end
      item
        Caption = 'Data'
        Width = 300
      end>
    TabOrder = 1
    ViewStyle = vsReport
  end
  object Button1: TButton
    Left = 280
    Top = 48
    Width = 153
    Height = 33
    Caption = 'Start'
    TabOrder = 2
    OnClick = Button1Click
  end
end


Unit1.pas
=======

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
  IdHTTP, StdCtrls, ComCtrls;

type

  TStatus=(stPause,stRunning);

  TForm1 = class(TForm)
    ListBox1: TListBox;
    ListView1: TListView;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    FRunningThreadCount:Integer;
    FThreadList:TList;
    function AddThread(TreeIndex:Integer;Url:String):TStatus;
    function InsertThread(Index,TreeIndex:Integer;Url:String):TStatus;
    procedure TerminateThread(Sender: TObject);
    procedure ExecuteStartNext;
  public
    { Public declarations }
  end;

type

  TThreadForm1     =  class(TThread)
  private
     // Private declarations
     FForm:         TForm1;
     IdHTTP1:  TIdHTTP;
     FUrl:String;
     Fgoogledata:String;
  protected
     // Protected declarations
     procedure      AfterSend;
     procedure      BeforeSend;
     procedure      Execute; override;
  public
     FItemIndex:Integer;
     FStatus:TStatus;
     // Public declarations
     function GetGoogleData(URL : string) : string;
     constructor Create(Form: TForm1;ItemIndex:Integer;Url:String;Status:TStatus);
     procedure Main;
     procedure Continue;
     procedure Pause;
  end;


var
  Form1: TForm1;

Const MaxThreadCount=5;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var i:Integer;
begin
  for i:=0 to ListBox1.Count-1 do
  begin
     ListView1.Items.Add.Caption := ListBox1.Items.Strings[i];
     AddThread(i,ListBox1.Items.Strings[i]);
  end;
end;

procedure TThreadForm1.Main;
begin
  FForm.ListView1.Items.Item[FItemIndex].SubItems.Add(Fgoogledata);
end;

procedure TThreadForm1.Continue;
begin
  Resume;
  FStatus:=stRunning;
end;

procedure TThreadForm1.Pause;
begin
  Suspend;
  FStatus:=stPause;
end;


constructor TThreadForm1.Create(Form: TForm1;ItemIndex:Integer;Url:String;Status:TStatus);
begin
  // Set parameters
  FForm:=Form;
  FItemIndex:=ItemIndex;
  FUrl:=Url;
  // Perform inherited (don't suspend)
  FStatus:=Status;
  inherited Create(FStatus=stPause);
  // Set thread props
  FreeOnTerminate:=True;
  Priority:=tpLower;
  OnTerminate:=Form.TerminateThread;
end;

procedure TThreadForm1.BeforeSend;
begin
  IdHTTP1 := TIdHTTP.Create(nil);
end;

procedure TThreadForm1.AfterSend;
begin

end;

procedure TThreadForm1.Execute;
begin
  // ---- Set IdHTTP2 settings ---- //

     try
        BeforeSend;
        Fgoogledata:=GetGoogleData(FUrl);
        Synchronize(Main);
        AfterSend;
     finally
        IdHTTP1.Free;
     end;

end;




function TThreadForm1.GetGoogleData(URL : string) : string;
var
   GoogleResponse: TStringList;
begin
  try
   GoogleResponse := TStringList.Create;
   IdHTTP1.HandleRedirects := true;
   GoogleResponse.Text := IdHTTP1.Get(URL);
   result := GoogleResponse.Text;
  finally
   GoogleResponse.Free;
  end;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FThreadList:=TList.Create;
  FRunningThreadCount:=0;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FThreadList.Free;
end;

function TForm1.AddThread(TreeIndex:Integer;Url:String):TStatus;
begin
  if FRunningThreadCount<MaxThreadCount then
  begin
    Result:=stRunning;
    inc(FRunningThreadCount);
  end else Result:=stPause;
  FThreadList.Add(TThreadForm1.Create(Self,TreeIndex,Url,Result));
end;

function TForm1.InsertThread(Index,TreeIndex:Integer;Url:String):TStatus;
begin
  if FRunningThreadCount<MaxThreadCount then
  begin
    Result:=stRunning;
    inc(FRunningThreadCount);
  end else Result:=stPause;
  FThreadList.Insert(Index,TThreadForm1.Create(Self,TreeIndex,Url,Result));
end;

procedure TForm1.TerminateThread(Sender: TObject);
begin
  FThreadList.Delete(FThreadList.IndexOf(TThreadForm1(Sender)));
  Dec(FRunningThreadCount);
  ExecuteStartNext;
end;

procedure TForm1.ExecuteStartNext;
var i:Integer;
begin
   i:=0;
   while i<FThreadList.Count do
   begin
      if TThreadForm1(FThreadList.Items[i]).FStatus=stPause then
      begin
         if FRunningThreadCount<MaxThreadCount then
         begin
           inc(FRunningThreadCount);
           TThreadForm1(FThreadList.Items[i]).Continue;
         end;
         Break;
      end;
      inc(i);
   end;
end;

end.
0
Comment
Question by:triz99
5 Comments
 
LVL 21

Expert Comment

by:ziolko
ID: 19638419
since your thread's execute has no loop checking for terminate flag you cannot stop thread with .Terminate method, however you can try to kill it with TerminateThread()

ziolko.
0
 
LVL 9

Expert Comment

by:sas13
ID: 19639137
try to use TIdHTTP.OnWork event to stop reading data and terminate thread

procedure TThreadForm1.IdHTTP1Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
begin
  if Terminated then begin
     IdHTTP1.Disconnect;
     // or for example raise Exception: raise Exceptin.Create(nil);
  end
end;

procedure TThreadForm1.Execute;
begin
  try
     BeforeSend;
     if Terminated then
       Exit;
     IdHTTP1.OnWork := IdHTTP1Work;
     Fgoogledata:=GetGoogleData(FUrl);
     if Terminated then
       Exit;
     Synchronize(Main);
     AfterSend;
   finally
      IdHTTP1.Free;
   end;
end;

for stops all threads, you must call Treminate method for all of your TThreads
0
 

Author Comment

by:triz99
ID: 19641210
I want to terminate all runings threads.
0
 
LVL 10

Accepted Solution

by:
dinilud earned 2000 total points
ID: 19644037
i agree with Ziolko's solution.



Unit1.dfm
=========

object Form1: TForm1
  Left = 57
  Top = 132
  Width = 674
  Height = 418
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnClose = FormClose
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object ListBox1: TListBox
    Left = 8
    Top = 8
    Width = 225
    Height = 137
    ItemHeight = 13
    Items.Strings = (
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.yahoo.co.in/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.yahoo.co.in/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.yahoo.co.in/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.yahoo.co.in/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.google.co.in/'
      'http://www.experts-exchange.com/'
      'http://www.yahoo.co.in/')
    TabOrder = 0
  end
  object ListView1: TListView
    Left = 8
    Top = 152
    Width = 649
    Height = 201
    Columns = <
      item
        Caption = 'Path'
        Width = 200
      end
      item
        Caption = 'Data'
        Width = 300
      end>
    TabOrder = 1
    ViewStyle = vsReport
  end
  object Button1: TButton
    Left = 280
    Top = 48
    Width = 153
    Height = 33
    Caption = 'Start'
    TabOrder = 2
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 472
    Top = 48
    Width = 145
    Height = 41
    Caption = 'Terminate All Threads'
    TabOrder = 3
    OnClick = Button2Click
  end
end


Unit1.pas
=========

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
  IdHTTP, StdCtrls, ComCtrls;

type

  TStatus=(stPause,stRunning);

  TForm1 = class(TForm)
    ListBox1: TListBox;
    ListView1: TListView;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    FRunningThreadCount:Integer;
    FThreadList:TList;
    FTerminateAllThread:Boolean;
    function AddThread(TreeIndex:Integer;Url:String):TStatus;
    function InsertThread(Index,TreeIndex:Integer;Url:String):TStatus;
    procedure TerminateThread(Sender: TObject);
    procedure ExecuteStartNext;
  public
    { Public declarations }
  end;

type

  TThreadForm1     =  class(TThread)
  private
     // Private declarations
     FForm:         TForm1;
     IdHTTP1:  TIdHTTP;
     FUrl:String;
     Fgoogledata:String;
  protected
     // Protected declarations
     procedure      AfterSend;
     procedure      BeforeSend;
     procedure      Execute; override;
  public
     FItemIndex:Integer;
     FStatus:TStatus;
     // Public declarations
     function GetGoogleData(URL : string) : string;
     constructor Create(Form: TForm1;ItemIndex:Integer;Url:String;Status:TStatus);
     procedure Main;
     procedure Continue;
     procedure Pause;
  end;


var
  Form1: TForm1;

Const MaxThreadCount=5;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var i:Integer;
begin
  for i:=0 to ListBox1.Count-1 do
  begin
     ListView1.Items.Add.Caption := ListBox1.Items.Strings[i];
     AddThread(i,ListBox1.Items.Strings[i]);
  end;
end;

procedure TThreadForm1.Main;
begin
  FForm.ListView1.Items.Item[FItemIndex].SubItems.Add(Fgoogledata);
end;

procedure TThreadForm1.Continue;
begin
  Resume;
  FStatus:=stRunning;
end;

procedure TThreadForm1.Pause;
begin
  Suspend;
  FStatus:=stPause;
end;


constructor TThreadForm1.Create(Form: TForm1;ItemIndex:Integer;Url:String;Status:TStatus);
begin
  // Set parameters
  FForm:=Form;
  FItemIndex:=ItemIndex;
  FUrl:=Url;
  // Perform inherited (don't suspend)
  FStatus:=Status;
  inherited Create(FStatus=stPause);
  // Set thread props
  FreeOnTerminate:=True;
  Priority:=tpLower;
  OnTerminate:=Form.TerminateThread;
end;

procedure TThreadForm1.BeforeSend;
begin
  IdHTTP1 := TIdHTTP.Create(nil);
end;

procedure TThreadForm1.AfterSend;
begin

end;

procedure TThreadForm1.Execute;
begin
  // ---- Set IdHTTP2 settings ---- //

     try
        BeforeSend;
        Fgoogledata:=GetGoogleData(FUrl);
        Synchronize(Main);
        AfterSend;
     finally
        IdHTTP1.Free;
     end;

end;




function TThreadForm1.GetGoogleData(URL : string) : string;
var
   GoogleResponse: TStringList;
begin
  try
   GoogleResponse := TStringList.Create;
   IdHTTP1.HandleRedirects := true;
   GoogleResponse.Text := IdHTTP1.Get(URL);
   result := GoogleResponse.Text;
  finally
   GoogleResponse.Free;
  end;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FThreadList:=TList.Create;
  FRunningThreadCount:=0;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FThreadList.Free;
end;

function TForm1.AddThread(TreeIndex:Integer;Url:String):TStatus;
begin
  if FRunningThreadCount<MaxThreadCount then
  begin
    Result:=stRunning;
    inc(FRunningThreadCount);
  end else Result:=stPause;
  FThreadList.Add(TThreadForm1.Create(Self,TreeIndex,Url,Result));
end;

function TForm1.InsertThread(Index,TreeIndex:Integer;Url:String):TStatus;
begin
  if FRunningThreadCount<MaxThreadCount then
  begin
    Result:=stRunning;
    inc(FRunningThreadCount);
  end else Result:=stPause;
  FThreadList.Insert(Index,TThreadForm1.Create(Self,TreeIndex,Url,Result));
end;

procedure TForm1.TerminateThread(Sender: TObject);
begin
  FThreadList.Delete(FThreadList.IndexOf(TThreadForm1(Sender)));
  Dec(FRunningThreadCount);
  ExecuteStartNext;
end;

procedure TForm1.ExecuteStartNext;
var i:Integer;
begin
   i:=0;
   while i<FThreadList.Count do
   begin
      if TThreadForm1(FThreadList.Items[i]).FStatus=stPause then
      begin
         if FRunningThreadCount<MaxThreadCount then
         begin
           inc(FRunningThreadCount);
           TThreadForm1(FThreadList.Items[i]).Continue;
         end;
         Break;
      end;
      inc(i);
   end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Button2.Enabled:=False;
  Screen.Cursor:=crHourGlass;
  FTerminateAllThread:=True;
  While FThreadList.Count>0 do
  begin
    Windows.TerminateThread(TThreadForm1(FThreadList.Items[0]).Handle,0);
    FThreadList.Delete(0);
  end;
  Screen.Cursor:=crDefault;
  Button2.Enabled:=True;
end;

end.
0
 
LVL 1

Expert Comment

by:deadjoe
ID: 19644162
I agree Ziolko's and Dinilud's solution.
If you must check the thread Terminated
proprty in the Execute method you can terminate your threads
by calling all threads Terminate method.
Calling FThreadList.Delete(FThreadList.IndexOf(TThreadForm1(Sender)));
don't terminate and don`t free's threads. It is good solution, as you do,
set the thread FreeOnTerminate property to true, and call the Terminate method.

procedure TThreadForm1.Execute;
begin
while not Terminated do
begin
     try
        BeforeSend;
        Fgoogledata:=GetGoogleData(FUrl);
        Synchronize(Main);
        AfterSend;
     finally
        IdHTTP1.Free;
     end;
end;

end;

0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Stellar Phoenix SQL Database Repair software easily fixes the suspect mode issue of SQL Server database. It is a simple process to bring the database from suspect mode to normal mode. Check out the video and fix the SQL database suspect mode problem.
If you are looking for an automated solution for backup single or multiple Office 365 user mailboxes to Outlook data file, then you can use Kernel Office 365 Backup & Restore tool. Go through the video to check out the steps to backup single or mult…

589 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question